2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
4 %************************************************************************
6 \section{Macros and global declarations for GranSim}
8 %************************************************************************
10 Dummy definitions if we are not compiling for GrAnSim.
14 #define GRAN_ALLOC_HEAP(n,liveness) /* nothing */
15 #define GRAN_UNALLOC_HEAP(n,liveness) /* nothing */
16 #define GRAN_FETCH() /* nothing */
17 #define GRAN_FETCH_AND_RESCHEDULE(liveness) /* nothing */
18 #define GRAN_RESCHEDULE(liveness, reenter) /* nothing */
19 #define GRAN_EXEC(arith,branch,loads,stores,floats) /* nothing */
20 #define GRAN_SPARK() /* nothing */
24 First the basic types specific to GrAnSim.
28 #define GRANSIMSTATS_BINARY RTSflags.GranFlags.granSimStats_Binary
30 #define GRANSIMSTATS_BINARY RTSflags.ParFlags.granSimStats_Binary
34 ullong msTime(STG_NO_ARGS);
35 # define CURRENT_TIME msTime()
36 # define TIME_ON_PROC(p) msTime()
38 # define CURRENT_PROC thisPE
43 #if !defined(COMPILING_GHC)
47 # define CURRENT_TIME CurrentTime[CurrentProc]
48 # define TIME_ON_PROC(p) CurrentTime[p]
49 # define CURRENT_PROC CurrentProc
52 #if defined(GRAN) || defined(PAR)
54 /* Granularity event types for output (see DumpGranEvent) */
55 enum gran_event_types {
56 GR_START = 0, GR_STARTQ,
57 GR_STEALING, GR_STOLEN, GR_STOLENQ,
58 GR_FETCH, GR_REPLY, GR_BLOCK, GR_RESUME, GR_RESUMEQ,
59 GR_SCHEDULE, GR_DESCHEDULE,
61 SP_SPARK, SP_SPARKAT, SP_USED, SP_PRUNED, SP_EXPORTED, SP_ACQUIRED,
64 GR_SYSTEM_START, GR_SYSTEM_END, /* only for debugging */
68 /* Prototypes of functions needed both in GRAN and PAR setup */
69 void DumpGranEvent PROTO((enum gran_event_types name, P_ tso));
70 void DumpRawGranEvent PROTO((PROC proc, PROC p, enum gran_event_types name, P_ tso, P_ node, I_ len));
71 void DumpStartEventAt PROTO((TIME time, PROC proc, PROC p, enum gran_event_types name,
72 P_ tso, P_ node, I_ len));
73 void DumpGranInfo PROTO((PROC proc, P_ tso, rtsBool mandatory_thread));
74 void DumpTSO PROTO((P_ tso));
76 void grterminate PROTO((TIME v));
77 void grputw PROTO((TIME v));
79 extern unsigned CurrentProc;
80 /* I have no idea what this is supposed to be in the PAR case WDP 96/03 */
82 #endif /* GRAN || PAR */
84 /* ---------- The rest of this file is GRAN only ---------- */
87 rtsBool any_idle PROTO((STG_NO_ARGS));
88 int idlers PROTO((STG_NO_ARGS));
91 Idle = 0, /* empty threadq */
92 Sparking, /* non-empty sparkq; FINDWORK has been issued */
93 Starting, /* STARTTHREAD has been issue */
94 Fetching, /* waiting for remote data (only if block-on-fetch) */
95 Fishing, /* waiting for remote spark/thread */
96 Busy /* non-empty threadq, with head of queue active */
99 typedef struct event {
100 PROC proc; /* Processor id */
101 PROC creator; /* Processor id of PE that created the event */
102 EVTTYPE evttype; /* Event type */
103 TIME time; /* Time at which event happened */
104 P_ tso; /* Associated TSO, if relevant, Nil_closure otherwise*/
105 P_ node; /* Associated node, if relevant, Nil_closure otherwise*/
106 sparkq spark; /* Associated SPARK, if relevant, NULL otherwise */
107 I_ gc_info; /* Counter of heap objects to mark (used in GC only)*/
111 /* Macros for accessing components of the event structure */
112 #define EVENT_PROC(evt) (evt->proc)
113 #define EVENT_CREATOR(evt) (evt->creator)
114 #define EVENT_TIME(evt) (evt->time)
115 #define EVENT_TYPE(evt) (evt->evttype)
116 #define EVENT_TSO(evt) (evt->tso)
117 #define EVENT_NODE(evt) (evt->node)
118 #define EVENT_SPARK(evt) (evt->spark)
119 #define EVENT_GC_INFO(evt) (evt->gc_info)
120 #define EVENT_NEXT(evt) (eventq)(evt->next)
122 /* Maximum number of PEs that can be simulated */
123 #define MAX_PROC (BITS_IN(W_))
126 extern W_ IdleProcs, Idlers;
129 /* Processor numbers to bitmasks and vice-versa */
130 #define MainProc 0 /* Id of main processor */
131 #define MAX_PRI 10000 /* max possible priority */
132 #define MAIN_PRI MAX_PRI /* priority of main thread */
134 /* GrAnSim uses IdleProcs as bitmask to indicate which procs are idle */
135 #define PE_NUMBER(n) (1l << (long)n)
136 #define ThisPE PE_NUMBER(CurrentProc)
137 #define MainPE PE_NUMBER(MainProc)
138 #define Everywhere (~0l)
141 #define IS_LOCAL_TO(ga,proc) ((1l << (long) proc) & ga)
143 #define GRAN_TIME_SLICE 1000 /* max time between 2 ReSchedules */
147 #define IS_IDLE(proc) (procStatus[proc] == Idle)
148 #define IS_SPARKING(proc) (procStatus[proc] == Sparking)
149 #define IS_STARTING(proc) (procStatus[proc] == Starting)
150 #define IS_FETCHING(proc) (procStatus[proc] == Fetching)
151 #define IS_FISHING(proc) (procStatus[proc] == Fishing)
152 #define IS_BUSY(proc) (procStatus[proc] == Busy)
153 #define ANY_IDLE (any_idle())
154 #define MAKE_IDLE(proc) do { procStatus[proc] = Idle; } while(0)
155 #define MAKE_SPARKING(proc) do { procStatus[proc] = Sparking; } while(0)
156 #define MAKE_STARTING(proc) do { procStatus[proc] = Starting; } while(0)
157 #define MAKE_FETCHING(proc) do { procStatus[proc] = Fetching; } while(0)
158 #define MAKE_FISHING(proc) do { procStatus[proc] = Fishing; } while(0)
159 #define MAKE_BUSY(proc) do { procStatus[proc] = Busy; } while(0)
163 #define IS_IDLE(proc) ((IdleProcs & PE_NUMBER((long)proc)) != 0l)
164 #define ANY_IDLE (Idlers > 0)
165 #define MAKE_IDLE(proc) do { \
166 if (!IS_IDLE(proc)) { \
168 IdleProcs |= PE_NUMBER(proc); \
169 procStatus[proc] = Idle; \
172 #define MAKE_BUSY(proc) do { \
173 if (IS_IDLE(proc)) { \
175 IdleProcs &= ~PE_NUMBER(proc); \
176 procStatus[proc] = Busy; \
181 /* Number of last event type */
184 /* Event Types (internal use only) */
185 #define STARTTHREAD 0 /* Start a newly created thread */
186 #define CONTINUETHREAD 1 /* Continue running the first thread in the queue */
187 #define RESUMETHREAD 2 /* Resume a previously running thread */
188 #define MOVESPARK 3 /* Move a spark from one PE to another */
189 #define MOVETHREAD 4 /* Move a thread from one PE to another */
190 #define FINDWORK 5 /* Search for work */
191 #define FETCHNODE 6 /* Fetch a node */
192 #define FETCHREPLY 7 /* Receive a node */
193 #define GLOBALBLOCK 8 /* Block a TSO on a remote node */
194 #define UNBLOCKTHREAD 9 /* Make a TSO runnable */
196 #if defined(GRAN_CHECK)
197 /* Prototypes of GrAnSim debugging functions */
198 void G_PRINT_NODE(P_);
200 void G_INFO_TABLE(P_);
201 void G_CURR_THREADQ(I_);
202 void G_THREADQ(P_, I_);
204 void G_EVENT(eventq, I_);
206 void G_PE_EQ(PROC, I_);
207 void G_SPARK(sparkq, I_);
208 void G_SPARKQ(sparkq, I_);
209 void G_CURR_SPARKQ(I_);
229 /* Interface to event queues */
230 extern eventq EventHd; /* global event queue */
231 extern char *event_names[];
232 eventq get_next_event PROTO(());
233 TIME get_time_of_next_event PROTO(());
234 void newevent PROTO((PROC proc, PROC creator, TIME time, EVTTYPE
235 evttype, P_ tso, P_ node, sparkq spark));
236 void prepend_event PROTO((eventq event));
237 eventq grab_event PROTO((STG_NO_ARGS));
238 void print_event PROTO((eventq event));
239 void print_eventq PROTO((eventq hd));
240 void print_spark PROTO((sparkq spark));
241 void print_sparkq PROTO((sparkq hd));
243 /* void DumpPruneEvent PROTO((PROC proc, sparkq spark)); */
245 I_ SaveSparkRoots PROTO((I_));
246 I_ SaveEventRoots PROTO((I_));
248 I_ RestoreSparkRoots PROTO((I_));
249 I_ RestoreEventRoots PROTO((I_));
251 IF_RTS(int init_gr_simulation PROTO((int, char **, int, char **));)
252 IF_RTS(void end_gr_simulation(STG_NO_ARGS);)
254 /* These constants are defaults for the RTS flags of GranSim */
256 /* Communication Cost Model (EDS-like), max_proc > 2. */
258 #define LATENCY 1000 /* Latency for single packet */
259 #define ADDITIONAL_LATENCY 100 /* Latency for additional packets */
260 #define BASICBLOCKTIME 10
261 #define FETCHTIME (LATENCY*2+MSGUNPACKTIME)
262 #define LOCALUNBLOCKTIME 10
263 #define GLOBALUNBLOCKTIME (LATENCY+MSGUNPACKTIME)
265 #define MSGPACKTIME 0 /* Cost of creating a packet */
266 #define MSGUNPACKTIME 0 /* Cost of receiving a packet */
267 #define MSGTIDYTIME 0 /* Cost of cleaning up after send */
269 #define MAX_FISHES 1 /* max no. of outstanding spark steals */
270 /* How much to increase GrAnSims internal packet size if an overflow
272 NB: This is a GrAnSim internal variable and is independent of the
273 simulated packet buffer size.
276 #define GRANSIM_DEFAULT_PACK_BUFFER_SIZE 200
277 #define REALLOC_SZ 50
279 /* extern W_ gran_mpacktime, gran_mtidytime, gran_munpacktime; */
281 /* Thread cost model */
282 #define THREADCREATETIME (25+THREADSCHEDULETIME)
283 #define THREADQUEUETIME 12 /* Cost of adding a thread to the running/runnable queue */
284 #define THREADDESCHEDULETIME 75 /* Cost of descheduling a thread */
285 #define THREADSCHEDULETIME 75 /* Cost of scheduling a thread */
286 #define THREADCONTEXTSWITCHTIME (THREADDESCHEDULETIME+THREADSCHEDULETIME)
288 /* Instruction Cost model (SPARC, including cache misses) */
290 #define BRANCH_COST 2
293 #define FLOAT_COST 1 /* ? */
295 #define HEAPALLOC_COST 11
297 #define PRI_SPARK_OVERHEAD 5
298 #define PRI_SCHED_OVERHEAD 5
300 /* Miscellaneous Parameters */
301 extern rtsBool DoFairSchedule;
302 extern rtsBool DoReScheduleOnFetch;
303 extern rtsBool SimplifiedFetch;
304 extern rtsBool DoStealThreadsFirst;
305 extern rtsBool DoAlwaysCreateThreads;
306 extern rtsBool DoThreadMigration;
307 extern rtsBool DoGUMMFetching;
308 extern I_ FetchStrategy;
309 extern rtsBool PreferSparksOfLocalNodes;
310 extern rtsBool DoPrioritySparking, DoPriorityScheduling;
311 extern I_ SparkPriority, SparkPriority2, ThunksToPack;
312 /* These come from debug options -bD? */
313 extern rtsBool NoForward;
314 extern rtsBool PrintFetchMisses;
316 extern TIME TimeOfNextEvent, EndOfTimeSlice; /* checked from the threaded world! */
317 extern I_ avoidedCS; /* Unused!! ToDo: Remake libraries and nuke this var */
318 extern rtsBool IgnoreEvents; /* HACK only for testing */
320 #if defined(GRAN_CHECK)
321 /* Variables for gathering misc statistics */
322 extern I_ tot_low_pri_sparks;
323 extern I_ rs_sp_count, rs_t_count, ntimes_total, fl_total, no_of_steals;
324 extern I_ tot_packets, tot_packet_size, tot_cuts, tot_thunks,
325 tot_sq_len, tot_sq_probes, tot_sparks, withered_sparks,
326 tot_add_threads, tot_tq_len, non_end_add_threads;
329 extern I_ fetch_misses;
330 #if defined(GRAN_COUNT)
331 extern I_ nUPDs, nUPDs_old, nUPDs_new, nUPDs_BQ, nPAPs, BQ_lens;
334 extern FILE *gr_file;
335 /* extern rtsBool no_gr_profile; */
336 /* extern rtsBool do_sp_profile; */
338 extern rtsBool NeedToReSchedule;
340 void GranSimAllocate PROTO((I_ n, P_ node, W_ liveness));
341 void GranSimUnAllocate PROTO((I_ n, P_ node, W_ liveness));
342 I_ GranSimFetch PROTO((P_ node));
343 void GranSimExec PROTO((W_ ariths, W_ branches, W_ loads, W_ stores, W_ floats));
344 void GranSimSpark PROTO((W_ local, P_ node));
345 void GranSimSparkAt PROTO((sparkq spark, P_ where, I_ identifier));
346 void GranSimSparkAtAbs PROTO((sparkq spark, PROC proc, I_ identifier));
347 void GranSimBlock PROTO((P_ tso, PROC proc, P_ node));
348 void PerformReschedule PROTO((W_, rtsBool));
350 #define GRAN_ALLOC_HEAP(n,liveness) \
351 GranSimAllocate_wrapper(n,0,0);
353 #define GRAN_UNALLOC_HEAP(n,liveness) \
354 GranSimUnallocate_wrapper(n,0,0);
358 #define GRAN_FETCH() \
359 GranSimFetch_wrapper(Node);
361 #define GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter) \
362 do { if(liveness_mask&LIVENESS_R1) \
364 GranSimFetch(Node); \
365 PerformReschedule(liveness_mask,reenter); \
366 RestoreAllStgRegs(); \
369 #define GRAN_RESCHEDULE(liveness_mask,reenter) \
370 PerformReschedule_wrapper(liveness_mask,reenter)
374 #define GRAN_FETCH() /*nothing */
376 #define GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter) \
377 do { if(liveness_mask&LIVENESS_R1) \
379 GranSimFetch(Node); \
380 PerformReschedule(liveness_mask,reenter); \
381 RestoreAllStgRegs(); \
384 #define GRAN_RESCHEDULE(liveness_mask,reenter) GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter)
388 #define THREAD_CONTEXT_SWITCH(liveness_mask,reenter) \
390 if (context_switch /* OR_INTERVAL_EXPIRED */) { \
391 GRAN_RESCHEDULE(liveness_mask,reenter); \
396 #define GRAN_EXEC(arith,branch,load,store,floats) \
397 GranSimExec_wrapper(arith,branch,load,store,floats);
401 #define GRAN_EXEC(arith,branch,load,store,floats) \
403 W_ cost = RTSflags.GranFlags.gran_arith_cost*arith + \
404 RTSflags.GranFlags.gran_branch_cost*branch + \
405 RTSflags.GranFlags.gran_load_cost*load + \
406 RTSflags.GranFlags.gran_store_cost*store + \
407 RTSflags.GranFlags.gran_float_cost*floats; \
408 TSO_EXECTIME(CurrentTSO) += cost; \
409 CurrentTime[CurrentProc] += cost; \
414 #define GRAN_YIELD(liveness) \
416 if ( (CurrentTime[CurrentProc]>=EndOfTimeSlice) || \
417 ((CurrentTime[CurrentProc]>=TimeOfNextEvent) && \
418 (TimeOfNextEvent!=0) && !IgnoreEvents )) { \
419 DO_GRAN_YIELD(liveness); \
423 #define ADD_TO_SPARK_QUEUE(spark) \
424 STGCALL1(void,(),add_to_spark_queue,spark) \