/* Time-stamp: Basic functions for use in either GranSim or GUM. */ #if defined(PARALLEL_RTS) #include "Rts.h" // including Parallel.h #include "sm/Storage.h" #include "Printer.h" // info_hdr_type //#include "RtsFlags.h" //MSA: it is dperecated , just use Rts.h #include "GranSimRts.h" // for GR_ events -- MSA #include "ParallelRts.h" // needed for GlobalParStats -- HWL #include "RtsUtils.h" // for GR_ events -- MSA #include // for GR_ events -- MSA rtsBool UNTAG_CHECK(StgClosure *cl) //msa: used in HLComms.c and Global.c { return (GET_CLOSURE_TAG(cl)==0); } StgClosure * followFwdInfoPtr(StgInfoTable *info) //msa: defined in ParallelRts.h and used in Global.c { StgClosure *new_la; if (IS_FORWARDING_PTR(info)) { // alive! new_la = (StgClosure*)UN_FORWARDING_PTR(info); } else { new_la = (StgClosure*)NULL; } return new_la; } #if 0 // should use isGhostTSO in RtsUtils.c instead rtsBool isGhostrTSO(StgTSO *tso) { return (//tso->why_blocked==BlockedOnRemoteFetch && tso->what_next>MAX_WHAT_NEXT); // UNACCEPTABLE HWL HACK: constant MAX_WHAT_NEXT to identify ghost TSO } #endif /* MSA: functions required for GR_ events */ /* Needed for dumping routines */ //MSA :(50 - 58) coppied from gum4 include/Parallel.h # define NODE_STR_LEN 20 # define TIME_STR_LEN 120 # define TIME rtsTime # define CURRENT_TIME (msTime()) # define TIME_ON_PROC(p) (msTime()) # define CURRENT_PROC thisPE # define BINARY_STATS RtsFlags.ParFlags.ParStats.Binary extern nat sparksIgnored, sparksCreated, threadsIgnored, threadsCreated; //extern nat advisory_thread_count; //MSA: defined in ParallelRts.h :107 #define stgCast(ty,e) ((ty)(e)) // Msa: coppied from Gum4: StgTypes.h :199 /* msa :coppied from gum4 (62-191) include/TSO.h*/ FILE *gr_file = NULL; char gr_filename[STATS_FILENAME_MAXLEN]; //GlobalParStats globalParStats; // msa : defined in ParInit.c ullong startTime = 0; void init_gr_stats (void); void init_gr_simulation(rts_argc, rts_argv, prog_argc, prog_argv) char *prog_argv[], *rts_argv[]; int prog_argc, rts_argc; { nat i; char time_string[TIME_STR_LEN], node_str[NODE_STR_LEN]; char *extension = RtsFlags.ParFlags.ParStats.Binary ? "gb" : "gr"; sprintf(gr_filename, GR_FILENAME_FMT_GUM, prog_argv[0], thisPE, extension); if (!RtsFlags.ParFlags.ParStats.Full) return; if (RtsFlags.ParFlags.ParStats.Global) init_gr_stats(); if ((gr_file = fopen(gr_filename, "w")) == NULL) barf("Can't open activity report file %s\n", gr_filename); setbuf(gr_file, NULL); /* turn buffering off */ /* write header with program name, options and setup to gr_file */ fputs("=", gr_file); for (i = 0; i < prog_argc; ++i) { fputs(prog_argv[i], gr_file); fputc(' ', gr_file); } if (rts_argc > 0) { fputs("+RTS ", gr_file); for (i = 0; i < rts_argc; ++i) { fputs(rts_argv[i], gr_file); fputc(' ', gr_file); } } fputc('\n', gr_file); /* record the absolute start time to allow synchronisation of log-files */ fputs("Start-Time: ", gr_file); fputs(time_str(), gr_file); fputc('\n', gr_file); fputs("+++++ ", gr_file); fputc('\n', gr_file); ASSERT(startTime==0); // startTime = msTime(); startTime = CURRENT_TIME; ullong_format_string(CURRENT_TIME, time_string, rtsFalse/*no commas!*/); fprintf(gr_file, "PE %2u [%s]: TIME\n", thisPE, time_string); printf("\n msa:******** after writing to the gr file************************* ... \n"); # if 0 ngoq Dogh'q' vImuS IF_PAR_DEBUG(verbose, belch("== Start-time: %ld (%s)", startTime, time_string)); if (startTime > LL(1000000000)) { fprintf(gr_file, "PE %2u [%lu%lu]: TIME\n", thisPE, (rtsTime) (startTime / LL(1000000000)), (rtsTime) (startTime % LL(1000000000))); } else { fprintf(gr_file, "PE %2u [%lu]: TIME\n", thisPE, (TIME) startTime); } /* binary log files are currently not supported */ if (RtsFlags.GranFlags.GranSimStats.Binary) grputw(sizeof(rtsTime)); # endif return; } #if !defined(DEBUG) void init_gr_stats (void) { /* nothing */ } // HWL TODO: why is init_gr_stats needed at all in !DEBUG? FIXME #else void init_gr_stats (void) { // memset(&globalParStats, '\0', sizeof(GlobalParStats)); globalParStats.tot_mark_GA = globalParStats.tot_rebuild_GA = globalParStats.tot_free_GA = globalParStats.res_mark_GA = globalParStats.res_rebuild_GA = globalParStats.res_free_GA = globalParStats.tot_size_GA = globalParStats.res_size_GA = globalParStats.tot_global = globalParStats.tot_local = 0; globalParStats.cnt_mark_GA = globalParStats.cnt_rebuild_GA = globalParStats.cnt_free_GA = globalParStats.res_free_GA = globalParStats.local_alloc_GA = 0; globalParStats.time_mark_GA = 0.0; globalParStats.time_rebuild_GA = 0.0; globalParStats.time_sparks = 0.0; globalParStats.time_pack = 0.0; globalParStats.res_sp = globalParStats.res_tp = globalParStats.tot_sp = globalParStats.tot_tp = globalParStats.cnt_sp = globalParStats.cnt_tp = globalParStats.emp_sp = globalParStats.emp_tp = globalParStats.tot_db = 0; //msa: add globalParStats.tot_db globalParStats.tot_packets = globalParStats.tot_packet_size = globalParStats.tot_thunks = globalParStats.res_packet_size = globalParStats.res_thunks = globalParStats.rec_res_packet_size = globalParStats.rec_res_thunks = 0; globalParStats.tot_fish_mess = globalParStats.tot_fetch_mess = globalParStats.tot_resume_mess = globalParStats.tot_schedule_mess = 0; globalParStats.rec_fish_mess = globalParStats.rec_resume_mess = globalParStats.rec_schedule_mess = 0; globalParStats.rec_fetch_mess = 0; #if defined(DIST) globalParStats.tot_reval_mess = 0; globalParStats.rec_reval_mess = 0; #endif globalParStats.tot_threads_created = globalParStats.tot_sparks_created = globalParStats.tot_sparks_ignored = globalParStats.tot_sparks_marked = globalParStats.res_sparks_created = globalParStats.res_sparks_ignored = globalParStats.res_sparks_marked = 0; globalParStats.tot_yields = globalParStats.tot_stackover = globalParStats.tot_heapover = 0; globalParStats.tot_arrs = globalParStats.tot_arr_size = 0; } #endif void end_gr_simulation(void) { char time_string[TIME_STR_LEN]; ullong_format_string(CURRENT_TIME-startTime, time_string, rtsFalse/*no commas!*/); #if defined(DEBUG) fprintf(stderr, "Computation finished after @ %s @ ms. %d sparks created, %d sparks ignored. Check %s for details.\n", time_string, sparksCreated, sparksIgnored, gr_filename); /*fprintf(stderr, "Computation finished after @ %s @ ms. Check %s for details.\n", time_string, gr_filename);*/ #endif if (RtsFlags.ParFlags.ParStats.Full) fclose(gr_file); } //@node Dumping routines, , Global statistics //@subsection Dumping routines //@cindex DumpGranEvent void DumpGranEvent(name, tso) GranEventType name; StgTSO *tso; { DumpRawGranEvent(CURRENT_PROC, (PEs)0, name, tso, &stg_END_TSO_QUEUE_closure, (StgInt)0, (StgInt)0); } void DumpRawGranEvent(proc, p, name, tso, node, sparkname, len) PEs proc, p; /* proc ... where it happens; p ... where node lives */ GranEventType name; StgTSO *tso; StgClosure *node; StgInt sparkname, len; { # if defined(GRAN) DumpVeryRawGranEvent(TIME_ON_PROC(proc), proc, p, name, tso, node, sparkname, len); # elif defined(PARALLEL_RTS) DumpVeryRawGranEvent(CURRENT_TIME, proc, p, name, tso, node, sparkname, len); # endif } //@cindex DumpVeryRawGranEvent void DumpVeryRawGranEvent(time, proc, p, name, tso, node, sparkname, len) rtsTime time; PEs proc, p; /* proc ... where it happens; p ... where node lives */ GranEventType name; StgTSO *tso; StgClosure *node; StgInt sparkname, len; { //printf("MSA******************\n"); FILE *output_file; // DEBUGGING ONLY !!!!!!!!!!!!!!!!!!!!!!!!!1 StgWord id; char time_string[TIME_STR_LEN], node_str[NODE_STR_LEN]; # if defined(GRAN) ullong_format_string(time, time_string, rtsFalse/*no commas!*/); # elif defined(PARALLEL_RTS) ullong_format_string(time, time_string, rtsFalse/*no commas!*/); # endif output_file = gr_file; //printf("#nMSA******************\n"); # if defined(GRAN) if (RtsFlags.GranFlags.GranSimStats.Full) ASSERT(output_file!=NULL); if (RtsFlags.GranFlags.GranSimStats.Suppressed) return; # elif defined(PARALLEL_RTS) // if (RtsFlags.ParFlags.ParStats.Full) //msa .. this field ?? why? ASSERT(output_file!=NULL); // you are right, this should hold in all setups that reach this point HWL'Jan13 if (RtsFlags.ParFlags.ParStats.Suppressed) return; # endif id = tso == NULL ? -1 : tso->id; if (node==stgCast(StgClosure*,&stg_END_TSO_QUEUE_closure)) strcpy(node_str,"________"); /* "END_TSO_QUEUE"); */ else sprintf(node_str,"0x%-6lx",node); if (name > GR_EVENT_MAX) name = GR_EVENT_MAX; if (BINARY_STATS) barf("binary log files not yet supported"); #if 0 /* ToDo: fix code for writing binary GrAnSim statistics */ switch (name) { case GR_START: case GR_STARTQ: grputw(name); grputw(proc); abort(); /* die please: a single word */ /* doesn't represent long long times */ grputw(TIME_ON_PROC(proc)); grputw((StgWord)node); break; case GR_FETCH: case GR_REPLY: case GR_BLOCK: grputw(name); grputw(proc); abort(); /* die please: a single word */ /* doesn't represent long long times */ grputw(TIME_ON_PROC(proc)); /* this line is bound to */ grputw(id); /* do the wrong thing */ break; default: grputw(name); grputw(proc); abort(); /* die please: a single word */ /* doesn't represent long long times */ grputw(TIME_ON_PROC(proc)); grputw((StgWord)node); } #endif else /* !BINARY_STATS */ switch (name) { case GR_START: case GR_STARTQ: ullong_format_string(CURRENT_TIME-startTime, time_string, rtsFalse/*no commas!*/); //MSA fprintf(output_file,"PE %2u [%s]: %-9s\t%lx\t%s\t[SN %u]\t[sparks %u]\n", proc,time_string,gran_event_names[name], id,node_str,sparkname,len); break; case GR_FETCH: case GR_REPLY: case GR_BLOCK: case GR_STOLEN: case GR_STOLENQ: case GR_STEALING: ullong_format_string(CURRENT_TIME-startTime, time_string, rtsFalse/*no commas!*/); //MSA fprintf(output_file, "PE %2u [%s]: %-9s\t \t%lx \t%s\t(from %2u)\n", proc, time_string, gran_event_names[name], id,node_str,p); break; case GR_RESUME: case GR_RESUMEQ: ullong_format_string(CURRENT_TIME-startTime, time_string, rtsFalse/*no commas!*/); //MSA fprintf(output_file,"PE %2u [%s]: %-9s\t%lx \n", proc,time_string/*- startTime MSA*/,gran_event_names[name],id); break; case GR_SCHEDULE: case GR_DESCHEDULE: // HWL'Jan13: I'm ignoring these for now (mostly boring); TODO: optionally turn them on ullong_format_string(CURRENT_TIME-startTime, time_string, rtsFalse/*no commas!*/); //MSA fprintf(output_file, "PE %2u [%s]: %-9s\t \t%lx \t%s\t(from %2u)\n", proc, time_string, gran_event_names[name], id,node_str,p); break; case GR_ALLOC: ullong_format_string(CURRENT_TIME-startTime, time_string, rtsFalse/*no commas!*/); //MSA fprintf(output_file,"PE %2u [%s]: %-9s\t%lx\t \tallocating %u words\n", proc,time_string/*- startTime MSA*/,gran_event_names[name],id,len); break; default: // HWL'Jan13: this might crash because name is unknown; better abort with an uknown GRAN_EVENT error ullong_format_string(CURRENT_TIME-startTime, time_string, rtsFalse/*no commas!*/); //MSA fprintf(output_file,"PE %2u [%s]: %9s\t%lx\t%s\t[sparks %u]\n", proc,time_string/*- startTime MSA*/,gran_event_names[name],id,node_str,len); } // printf("MSA******************\n : PE %2u [%s]: %-9s\t%lx\t%s\t[sparks %u]\n", // proc,time_string,gran_event_names[name],id,node_str,len); } //@cindex DumpGranInfo void DumpEndEvent(proc, tso, mandatory_thread) PEs proc; StgTSO *tso; rtsBool mandatory_thread; { FILE *output_file; // DEBUGGING ONLY !!!!!!!!!!!!!!!!!!!!!!!!!1 char time_string[TIME_STR_LEN]; # if defined(GRAN) ullong_format_string(TIME_ON_PROC(proc), time_string, rtsFalse/*no commas!*/); # elif defined(PARALLEL_RTS) ullong_format_string(CURRENT_TIME, time_string, rtsFalse/*no commas!*/); # endif output_file = gr_file; ASSERT(output_file!=NULL); #if defined(GRAN) if (RtsFlags.GranFlags.GranSimStats.Suppressed) return; #endif if (BINARY_STATS) { barf("binary log files not yet supported"); #if 0 grputw(GR_END); grputw(proc); abort(); /* die please: a single word doesn't represent long long times */ grputw(CURRENT_TIME); /* this line is bound to fail */ grputw(tso->id); //#ifdef PAR #ifdef (PAR) grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); grputw(0); #else grputw(tso->gran.sparkname); grputw(tso->gran.startedat); grputw(tso->gran.exported); grputw(tso->gran.basicblocks); grputw(tso->gran.allocs); grputw(tso->gran.exectime); grputw(tso->gran.blocktime); grputw(tso->gran.blockcount); grputw(tso->gran.fetchtime); grputw(tso->gran.fetchcount); grputw(tso->gran.localsparks); grputw(tso->gran.globalsparks); #endif grputw(mandatory_thread); #endif /* 0 */ } else { /* * NB: DumpGranEvent cannot be used because PE may be wrong * (as well as the extra info) */ fprintf(output_file, "PE %2u [%s]: END %lx, SN %u, ST %lu, EXP %s, BB %u, HA %u, RT %u, BT %u (%u), FT %u (%u), LS %u, GS %u, MY %s\n" ,proc ,time_string ,tso->id #if defined(GRAN) ,tso->gran.sparkname ,tso->gran.startedat ,((tso->gran.exported) ? 'T' : 'F') ,tso->gran.basicblocks ,tso->gran.allocs ,tso->gran.exectime ,tso->gran.blocktime ,tso->gran.blockcount ,tso->gran.fetchtime ,tso->gran.fetchcount ,tso->gran.localsparks ,tso->gran.globalsparks #elif defined(PAR) ,tso->par.sparkname ,tso->par.startedat ,(tso->par.exported) ? "T" : "F" ,tso->par.basicblocks ,tso->par.allocs ,tso->par.exectime ,tso->par.blocktime ,tso->par.blockcount ,tso->par.fetchtime ,tso->par.fetchcount ,tso->par.localsparks ,tso->par.globalsparks #endif ,(mandatory_thread ? "T" : "F") ); } } #endif /* PARALLEL_RTS */