/* -------------------------------------------------------------------------- Time-stamp: Variables and functions specific to the parallel RTS (i.e. GUM or GranSim) ----------------------------------------------------------------------- */ #if defined(PARALLEL_RTS) /* whole file */ #ifndef PARALLEL_RTS_H #define PARALLEL_RTS_H #include "ParTicky.h" # define PACK_GA_SIZE 3 /* Size of a packed GA in words */ /* Size of a packed fetch-me in words */ # define PACK_FETCHME_SIZE (PACK_GA_SIZE + HEADERSIZE) #define PACK_BUFFER_SIZE(buffer) (PACK_BUFFER_HDR_SIZEW+DEBUG_HEADROOM+(buffer->size)) #define PACK_BUFFER_PAYLOAD_SIZE(buffer) (buffer->size) /* mainly for debugging */ #define SORT_OF_SAFE_UPD_IND(src,target) { \ if (src==target) { \ barf("PANIC: trying to update closure %p (%s) with IND to itself", src, info_type(UNTAG_CLOSURE(src))); \ } else if (get_itbl(UNTAG_CLOSURE(target))->type==IND) { \ StgClosure *closure = UNWIND_IND(UNTAG_CLOSURE(target)); \ if (closure==src) {\ barf("PANIC: trying to update closure %p (%s) with IND to itself", src, info_type(UNTAG_CLOSURE(src))); \ }\ }\ UPD_IND(src,target);\ } // IF_PAR_DEBUG(pack,if (get_itbl(UNTAG_CLOSURE(src))->type==FETCH_ME) { debugBelch("**## UPD_IND of FM @ %p to %p\n>>> %x %x %x %x",UNTAG_CLOSURE(src),UNTAG_CLOSURE(target),*UNTAG_CLOSURE(src),*(UNTAG_CLOSURE(src)+1),*(UNTAG_CLOSURE(src)+2),*(UNTAG_CLOSURE(src)+3));}) \ // needed in various places; should go into a global .h file -- HWL GUM6EDEN #define MIN_GA_WEIGHT 4 /* smallest legal weight; values lower than this are tags; see Global.c:splitWeight and Pack:isOffset etc -- HWL GUM6 */ #define MAX_GA_STR_LEN 40 #define MAX_GALA_STR_LEN 80 // used as args to sendFish #define NEW_FISH_AGE 0 #define NEW_FISH_HISTORY 0 #define NEW_FISH_HUNGER 0 #define FISH_LIFE_EXPECTANCY 10 // these used to be in includes/Parallel.h, but they don't have to be // entry to scheduler for remote PEs, in Schedule.c, called from Main.c void startWorking(Capability *cap); // Runtimetable: linked list of processes // in RTTables.c // NO: this should be in includes/rts/Parallel.h // void initRTT(void); // init for process list and internal variables // ports: declared in RtsTypes.h, constants here #define PORTSIZE sizeof(Port)/sizeof(StgWord) // fixed system ports: RTS port and NoPort constant // NO: now in rts/parallel/RTTables.h // extern Port RtsPort, NoPort; /* Port RtsPort = Port {thisPe, 0, 0}; */ /* Port NoPort = Port {0, 0, 0}; */ /* delay (in us) between dying fish returning and sending out a new fish */ #define FISH_DELAY 1000 /* max no. of outstanding spark steals */ #define MAX_FISHES 1 /* max no. of outstanding spark steals */ #define MAX_THREADS 1024 /* spark buffer size, ie. max no. of local sparks */ #define MAX_LOCAL_SPARKS 1024 /* low- and high-watermarks for spark pool */ #define SPARK_LWM 1 #define SPARK_HWM 10 #define SPARK_POOLS 2 // minimum sizes for mSPARK_POOLessages and buffers: // messages must contain tag as a data field, plus a separator #define MSG_HEADER 2 // All messages contain a header and 2 ports, #define MIN_MSG ( 2*PORTSIZE + MSG_HEADER) // if we use message buffering, we must add a packet header: (RtsFlags.h to be included!) #define PACKET_HEADER (RtsFlags.ParFlags.BufferTime?3:0) // => minimum data space for a MessageBuffer (in words!) is max. msg.size: /* HWL NO: this is now in includes/rts/Parallel.h #define DATASPACEWORDS ( ((int) RtsFlags.ParFlags.packBufferSize/sizeof(StgWord)) \ + PACK_BUFFER_HDR_SIZEW \ + MIN_MSG + PACKET_HEADER) */ // extern variables // PVMComms.c or MPIComms.c // HWL NO: this is now in includes/rts/Parallel.h // extern rtsBool IAmMainThread; // extern nat nPEs; // extern nat thisPE; // DataComms.c extern nat targetPE; // ParInit.c extern rtsBool fishing; /* We have no fish out in the stream */ extern nat advisory_thread_count; /* number of threads (for par) created */ extern rtsTime next_fish_to_send_at; /* expected time of next fish */ extern rtsTime last_fish_arrived_at; /* Time of arrival of most recent fish*/ extern nat outstandingFishes; /* Number of active fishes */ //@cindex PendingFetches /* A list of fetch reply messages not yet processed; this list is filled by awaken_blocked_queue and processed by processFetches */ extern GALA *blockedFetches; // log messages extern FILE *par_log_file; extern nat totFISH, totSCHEDULE, totACK, totSPARK, totFREE, totFETCH; extern nat totPackets, totUnpacked; /* global structure for collecting statistics */ // prototypes // Global.c /* TODO: move this into one general, parallel-specific .h file */ StgClosure* UNWIND_IND(StgClosure *closureT); // tag-safe StgInfoTable* get_closure_info(StgClosure* node, nat *size, nat *ptrs, // tag-safe nat *nonptrs, nat *vhs); rtsBool initGAtables(void); StgClosure *GALAlookup(globalAddr *ga); globalAddr *LAGAlookup(StgClosure *addr); globalAddr *makeGlobal(StgClosure *closureT, rtsBool preferred); globalAddr *setRemoteGA(StgClosure *local_closureT, globalAddr *remote_ga, rtsBool preferred); void setFetchedLA (StgTSO *t); // HWL NO: this is now in includes/rts/Parallel.h // StgWord PackGA (StgWord pe, int slot); rtsBool isGhostrTSO(StgTSO *tso); void deallocGALA(GALA *bf_gc); void checkBFQ(Capability *cap, rtsBool checkBH); nat GALA_list_len (GALA *gala); globalAddr *addWeight(globalAddr *ga); // used in Pack.c void splitWeight(globalAddr *to, globalAddr *from); // used in Pack.c // Pack.c // GUM only void convertToFetchMe(StgRBH *rbh, globalAddr *ga); StgClosure *convertToRBH(StgClosure *closure); // Eden only StgClosure* PackToMemory(StgClosure* graphroot, StgTSO* tso, Capability* cap); StgClosure* UnpackGraphWrapper(StgArrWords* packBufferArray, Capability* cap); // HLComms /* TODO: fix buffer types void processFetch (long *recvBuffer , Capability *cap ); void processFree(long *recvbuffer,Capability *cap); void processResume(Capability *cap, nat sender, long *recvBuffer ); void processSchedule(Capability *cap, nat sender, long *recvBuffer); void processAck(Capability *cap , long *recvBuffer); void sendFetch(globalAddr *rga, globalAddr *lga, int load); void sendFree(nat pe, int nelem, StgPtr data); void sendResume(globalAddr *rga, int nelem, rtsPackBuffer *packBuffer); void sendSchedule(nat origPE, int nelem, rtsPackBuffer *packBuffer); void sendAck(nat pe, int ngas, globalAddr *gagamap); */ void sendFish(nat destPE, nat origPE, int age, int history, int hunger); void packAndSendResume(StgClosure *closure, GALA *bf); // TODO: resolve clash btw HLComms.c and DataComms.c // nat choosePE(void); /* HWL HACK: compile time sanity checks; shouldn't be necessary at all */ #if defined(PAR) && defined(GRAN) # error "Both PAR and GRAN defined" #endif #if defined(DEBUG) /* Paranoia debugging: we add an end-of-buffer marker to every pack buffer (only when sanity checking RTS is enabled, of course) */ #define DEBUG_HEADROOM 1 #define END_OF_BUFFER_MARKER 0x1111bbbb #define GARBAGE_MARKER 0x1111eeee #else #define DEBUG_HEADROOM 0 #endif /* DEBUG */ /* Statistics info */ /* global structure for collecting statistics */ typedef struct GlobalParStats_ { /* GALA and LAGA table info */ nat tot_mark_GA, tot_rebuild_GA, tot_free_GA, res_mark_GA, res_rebuild_GA, res_free_GA, cnt_mark_GA, cnt_rebuild_GA, cnt_free_GA, res_size_GA, tot_size_GA, local_alloc_GA, tot_global, tot_local; /* time spent managing the GAs */ double time_mark_GA, time_rebuild_GA,time_active; /* spark queue stats */ nat res_sp, tot_sp, cnt_sp, emp_sp; nat tot_db ; //msa: add total deathbirth // nat tot_sq_len, tot_sq_probes, tot_sparks; /* thread queue stats */ nat res_tp, tot_tp, cnt_tp, emp_tp; //nat tot_add_threads, tot_tq_len, non_end_add_threads; /* packet statistics */ nat tot_packets, tot_packet_size, tot_thunks, res_packet_size, res_thunks, rec_packets, rec_packet_size, rec_thunks, rec_res_packet_size, rec_res_thunks; /* time spent packing stuff */ double time_pack, time_unpack; /* thread stats */ nat tot_threads_created; /* spark stats */ //nat pruned_sparks, withered_sparks; nat tot_sparks_created, tot_sparks_ignored, tot_sparks_marked, res_sparks_created, res_sparks_ignored, res_sparks_marked; // , sparks_created_on_PE[MAX_PROC]; double time_sparks; /* scheduling stats */ nat tot_yields, tot_stackover, tot_heapover; /* message statistics */ nat tot_fish_mess, tot_fetch_mess, tot_resume_mess, tot_schedule_mess; nat rec_fish_mess, rec_fetch_mess, rec_resume_mess, rec_schedule_mess; nat rec_ack_mess; #if defined(DIST) nat tot_reval_mess; nat rec_reval_mess; #endif /* blocking queue statistics rtsTime tot_bq_processing_time; nat tot_bq_len, tot_bq_len_local, tot_awbq, tot_FMBQs; */ /* specialised info on arrays (for GPH/Maple mainly) */ nat tot_arrs, tot_arr_size; } GlobalParStats; extern GlobalParStats globalParStats; void globalParStat_exit(void); // from Parallel.c StgClosure *followFwdInfoPtr(StgInfoTable *info); // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // VERY OLD STUFF; sort out and nuke #if defined(GRAN) || defined(PAR) #if defined(GRAN) /* Statistics info */ extern nat tot_packets, tot_packet_size, tot_cuts, tot_thunks; /* Pack.c */ rtsPackBuffer *PackNearbyGraph(StgClosure* closure, StgTSO* tso, nat *packBufferSize, GlobalTaskId dest); rtsPackBuffer *PackOneNode(StgClosure* closure, StgTSO* tso, nat *packBufferSize); rtsPackBuffer *PackTSO(StgTSO *tso, nat *packBufferSize); rtsPackBuffer *PackStkO(StgPtr stko, nat *packBufferSize); void PackFetchMe(StgClosure *closure); /* Unpack.c */ StgClosure* UnpackGraph(rtsPackBuffer* buffer); void InitPendingGABuffer(nat size); /* RBH.c */ StgClosure *convertToRBH(StgClosure *closure); void convertFromRBH(StgClosure *closure); /* HLComms.c */ rtsFetchReturnCode blockFetch(StgTSO* tso, PEs proc, StgClosure* bh); void blockThread(StgTSO *tso); #endif /* Pack.c */ void InitPackBuffer(void); rtsPackBuffer *PackNearbyGraph(StgClosure* closure, StgTSO* tso, nat *packBufferSize, GlobalTaskId dest); /* Unpack.c */ void CommonUp(StgClosure *src, StgClosure *dst); StgClosure *UnpackGraph(rtsPackBuffer *buffer, globalAddr **gamap, nat *nGAs); /* RBH.c */ StgClosure *convertToRBH(StgClosure *closure); void convertToFetchMe(StgRBH *rbh, globalAddr *ga); /* HLComms.c */ void blockFetch(StgBlockedFetch *bf, StgClosure *bh); void blockThread(StgTSO *tso); /* Global.c */ void GALAdeprecate(globalAddr *ga); /* HLComms.c */ nat pending_fetches_len(void); /* ParInit.c */ void initParallelSystem(void); void shutdownParallelSystem(StgInt n); void synchroniseSystem(void); void par_exit(I_); // HWL TODO: still needed? // rtsBool initCommBuffers(void) ; #endif /* this routine should be moved to a more general module; currently in Pack.c StgInfoTable* get_closure_info(StgClosure* node, nat *size, nat *ptrs, nat *nonptrs, nat *vhs, char *info_hdr_ty); */ void doGlobalGC(void); //@node GC routines, Debugging routines, Spark handling routines //@subsection GC routines #if defined(PAR) /* HLComms.c */ void freeRemoteGA(int pe, globalAddr *ga); void sendFreeMessages(void); void markPendingFetches(rtsBool major_gc); /* Global.c */ void markInPtrs(rtsBool full); void markOutPtrs(rtsBool full); void RebuildGAtables(rtsBool full); void RebuildLAGAtable(void); #endif //@node Debugging routines, Generating .gr profiles, GC routines //@subsection Debugging routines #if defined(PAR) void printGA (globalAddr *ga); void printGALA (GALA *gala); void printLAGAtable(void); rtsBool isOnLiveIndTable(globalAddr *ga); rtsBool isOnRemoteGATable(globalAddr *ga); void checkFreeGALAList(void); void checkFreeIndirectionsList(void); #endif //@node Generating .gr profiles, Index, Debugging routines //@subsection Generating .gr profiles #define STATS_FILENAME_MAXLEN 128 /* Where to write the log file */ //@cindex gr_file //@cindex gr_filename extern FILE *gr_file; extern char gr_filename[STATS_FILENAME_MAXLEN]; //@cindex init_gr_stats //@cindex init_gr_simulation //@cindex end_gr_simulation #if defined(PARALLEL_RTS)//msa void init_gr_stats (void); void init_gr_simulation(int rts_argc, char *rts_argv[], int prog_argc, char *prog_argv[]); void end_gr_simulation(void); #endif //msa /* TODO: move fcts in here (as static inline) StgInfoTable* get_closure_info(StgClosure* node, nat *size, nat *ptrs, nat *nonptrs, nat *vhs, char *info_hdr_ty); rtsBool IS_BLACK_HOLE(StgClosure* node); StgClosure *IS_INDIRECTION(StgClosure* node) ; StgClosure *UNWIND_IND (StgClosure *closure); */ #endif /* defined(PAR) || defined(GRAN) */ //@node Common macros, Index, Generating .gr profiles //@subsection Common macros #define LOOKS_LIKE_PTR(r) \ (LOOKS_LIKE_STATIC_CLOSURE(r) || \ ((HEAP_ALLOCED(r) && Bdescr((P_)r)->free != (void *)-1))) /* see Sanity.c for this kind of test; doing this in these basic fcts is paranoid (nuke it after debugging!) */ /* pathetic version of the check whether p can be a closure */ #define LOOKS_LIKE_COOL_CLOSURE(p) 1 //LOOKS_LIKE_GHC_INFO(get_itbl(p)) /* Is it a static closure (i.e. in the data segment)? */ \ /* #define LOOKS_LIKE_COOL_CLOSURE(p) \ ((LOOKS_LIKE_STATIC(p)) ? \ closure_STATIC(p) \ : !closure_STATIC(p) && LOOKS_LIKE_PTR(p)) */ #endif /* PARALLEL_RTS_H */ //@node Index, , Index //@subsection Index //@index //* IS_BLACK_HOLE:: @cindex\s-+IS_BLACK_HOLE //* IS_INDIRECTION:: @cindex\s-+IS_INDIRECTION //* end_gr_simulation:: @cindex\s-+end_gr_simulation //* get_closure_info:: @cindex\s-+get_closure_info //* gr_file:: @cindex\s-+gr_file //* gr_filename:: @cindex\s-+gr_filename //* init_gr_simulation:: @cindex\s-+init_gr_simulation //* unwindInd:: @cindex\s-+unwindInd //@end index