[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / includes / Parallel.lh
1 %
2 % (c) Kevin Hammond, Parade/AQUA Projects, Glasgow University, February 15th. 1995
3 %
4 %     This is for GUM only.
5 %
6 %************************************************************************
7 %*                                                                      *
8 \section[Parallel.lh]{Definitions for parallel machines}
9 %*                                                                      *
10 %************************************************************************
11
12 Multi-slurp protection:
13 \begin{code}
14 #ifndef Parallel_H
15 #define Parallel_H
16 \end{code}
17
18 This section contains definitions applicable only to programs compiled
19 to run on a parallel machine.  Some of these things can probably be
20 ripped out now that we don't store GAs in closures, but beware that
21 this {\em might} break GranSim, so check first!  KH
22
23 These basic definitions need to be around, one way or the other:
24 \begin{code}
25 #define PAR_FIXED_HDR                   (GA_HDR_SIZE)
26 #define PAR_HDR_POSN                    AFTER_INFO_HDR
27 #define AFTER_PAR_HDR                   (PAR_HDR_POSN+PAR_FIXED_HDR)
28
29 #define SET_PAR_HDR(closure,ga)         /* nothing */
30 #define SET_STATIC_PAR_HDR(closure)     /* nothing */
31 \end{code}
32
33 \begin{code}
34 # ifdef PAR
35 #  define MAX_PES       128             /* Maximum number of processors */
36
37 extern I_ do_gr_profile;
38 extern I_ do_sp_profile;
39 extern I_ do_gr_binary;
40
41 extern P_ PendingFetches;
42 extern GLOBAL_TASK_ID *PEs;
43
44 extern rtsBool IAmMainThread, GlobalStopPending;
45 extern rtsBool fishing;
46 extern GLOBAL_TASK_ID SysManTask;
47 extern int seed;                        /*pseudo-random-number generator seed:*/
48                                         /*Initialised in ParInit*/
49 extern I_ threadId;                     /*Number of Threads that have existed on a PE*/
50 extern GLOBAL_TASK_ID mytid;
51
52 extern int  nPEs;
53
54 extern rtsBool InGlobalGC;      /* Are we in the midst of performing global GC */
55
56 extern HashTable *pGAtoGALAtable;
57 extern HashTable *LAtoGALAtable;
58 extern GALA *freeIndirections;
59 extern GALA *liveIndirections;
60 extern GALA *freeGALAList;
61 extern GALA *liveRemoteGAs;
62 extern int thisPE;
63
64 void RunParallelSystem PROTO((StgPtr program_closure));
65 void initParallelSystem(STG_NO_ARGS);
66 void SynchroniseSystem(STG_NO_ARGS);
67
68 void registerTask PROTO((GLOBAL_TASK_ID gtid));
69 globalAddr *LAGAlookup PROTO((P_ addr));
70 P_ GALAlookup PROTO((globalAddr *ga));
71 globalAddr *MakeGlobal PROTO((P_ addr, rtsBool preferred));
72 globalAddr *setRemoteGA PROTO((P_ addr, globalAddr *ga, rtsBool preferred));
73 void splitWeight PROTO((globalAddr *to, globalAddr *from));
74 globalAddr *addWeight PROTO((globalAddr *ga));
75 void initGAtables(STG_NO_ARGS);
76 W_ taskIDtoPE PROTO((GLOBAL_TASK_ID gtid));
77 void RebuildLAGAtable(STG_NO_ARGS);
78
79 void *lookupHashTable PROTO((HashTable *table, StgWord key));
80 void insertHashTable PROTO((HashTable *table, StgWord key, void *data));
81 void freeHashTable PROTO((HashTable *table, void (*freeDataFun) PROTO((void *data))));
82 HashTable *allocHashTable(STG_NO_ARGS);
83 void *removeHashTable PROTO((HashTable *table, StgWord key, void *data));
84
85 extern void myexit PROTO((I_));
86 #  define EXIT myexit
87 #  define exit : error : Wrong exit!
88 # else
89 #  define EXIT exit
90 # endif
91
92 \end{code}
93
94 %************************************************************************
95 %*                                                                      *
96 \subsection[anti-parallel-SM]{But if we're {\em not} compiling for a parallel system...}
97 %*                                                                      *
98 %************************************************************************
99
100 Get this out of the way.  These are all null definitions.
101
102 \begin{code}
103 # if !(defined(GRAN) || defined(PAR))
104
105 #  define GA_HDR_SIZE                   0
106 #  define       GA(closure)                     /*nothing*/
107   
108 #  define SET_GA(closure,ga)            /* nothing */
109 #  define SET_STATIC_GA(closure)                /* nothing */
110 #  define SET_GRAN_HDR(closure,pe)        /* nothing */
111 #  define SET_STATIC_PROCS(closure)     /* nothing */
112   
113 #  define SET_TASK_ACTIVITY(act)                /* nothing */
114
115 # else
116 # ifdef GRAN
117
118 #  define GA_HDR_SIZE                   1
119
120 #  define PROCS_HDR_POSN                PAR_HDR_POSN
121 #  define PROCS_HDR_SIZE                1
122
123 /* Accessing components of the field */
124 #  define       PROCS(closure)          (*((P_)(closure)+PROCS_HDR_POSN))
125
126 #  define SET_PROCS(closure, procs) \
127         PROCS(closure) = (W_)(procs)    /* Set closure's location */
128 #  define SET_GRAN_HDR(closure,pe)      SET_PROCS(closure,pe)
129
130 #  if defined(GRAN_TNG)
131 #   define SET_STATIC_PROCS(closure)    , (W_) (Everywhere)
132 #  else
133 #   define SET_STATIC_PROCS(closure)    , (W_) (MainPE)
134 #  endif   /* GRAN_TNG */
135
136 #  define SET_TASK_ACTIVITY(act)        /* nothing */
137 \end{code}
138
139 %************************************************************************
140 %*                                                                      *
141 \subsection[parallel-GAs]{Parallel-only part of fixed headers (global addresses)}
142 %*                                                                      *
143 %************************************************************************
144
145 Definitions relating to the entire parallel-only fixed-header field.
146
147 On GUM, the global addresses for each local closure are stored in a separate
148 hash table, rather then with the closure in the heap.  We call @getGA@ to
149 look up the global address associated with a local closure (0 is returned
150 for local closures that have no global address), and @setGA@ to store a new
151 global address for a local closure which did not previously have one.
152
153 \begin{code}
154 # else /* it must be PARallel (to end of file) */
155
156 #  define GA_HDR_SIZE                   0
157   
158 #  define GA(closure)                   getGA(closure)
159   
160 #  define SET_GA(closure, ga)             setGA(closure,ga)
161 #  define SET_STATIC_GA(closure)
162 #  define SET_GRAN_HDR(closure,pe)
163 #  define SET_STATIC_PROCS(closure)
164   
165 #  define MAX_GA_WEIGHT                 0       /* Treat as 2^n */
166   
167 #  define PACK_GA(pe,slot)    ((((W_)(pe)) << (BITS_IN(W_)/2)) | ((W_)(slot)))
168
169 \end{code}
170
171 At the moment, there is no activity profiling for GUM.  This may change.
172
173 \begin{code}
174
175 #  define SET_TASK_ACTIVITY(act)
176
177 \end{code}
178
179 %************************************************************************
180 %*                                                                      *
181 \subsection[parallel-heap-objs]{Special parallel-only heap objects (`closures')}
182 %*                                                                      *
183 %************************************************************************
184
185 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 % NB: The following definitons are BOTH for GUM and GrAnSim -- HWL
187 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188
189 The rest of  this  file contains definitions  for  {\it  GUM  and GrAnSim}.
190 Although  we don't  create FetchMe   nodes in  GrAnSim  (we  simulate it by
191 bitmask  twiddling)  we use FetchMe_info   when converting  nodes into RBHs
192 (mainly  to keep the code as  close to GUM as  possible). So, we define all
193 the FetchMe related stuff in GrAnSim, too. % -- HWL
194
195 %************************************************************************
196 %*                                                                      *
197 \subsubsection[FETCHME-closures]{@FETCHME@ heap objects (`closures')}
198 %*                                                                      *
199 %************************************************************************
200
201 FetchMes are pointers into the global heap.  When evaluated, the value
202 they point to is read from the global heap.
203
204 A FetchMe closure has the form:
205
206 \begin{onlylatex}
207 \begin{center}
208 \end{onlylatex}
209 \begin{tabular}{||l|l||}\hline
210 \tr{FETCHME_info} & junk \\ \hline
211 \end{tabular}
212 \begin{onlylatex}
213 \end{center}
214 \end{onlylatex}
215
216 The argument word is a pointer (outside of the heap) to a globalAddr structure...
217 in particular, the one corresponding to the object to be fetched.  Note that
218 we can't just used the LAGA table, because weight-splitting may force us to
219 reassign a local GA to the @FetchMe@ so that we can give out new references.
220
221 A @FetchMe@ must have a valid @MUT_LINK@ field, because it may act as
222 a transition between an RBH on the OldMutables list and a BQ still on
223 the OldMutables list.
224
225
226 \begin{code}
227 #  define FETCHME_VHS                           IND_VHS
228 #  define FETCHME_HS                            IND_HS
229   
230 #  define FETCHME_GA_LOCN                       FETCHME_HS
231   
232 #  define FETCHME_CLOSURE_SIZE(closure)         IND_CLOSURE_SIZE(closure)
233 #  define FETCHME_CLOSURE_NoPTRS(closure)               0L
234 #  define FETCHME_CLOSURE_NoNONPTRS(closure)    (IND_CLOSURE_SIZE(closure)-IND_VHS)
235   
236 #  define SET_FETCHME_HDR(closure,infolbl,cc,size,ptrs) \
237 { SET_FIXED_HDR(closure,FetchMe_info,<bogus CC>);       \
238   SET_MUT_RESERVED_WORDS(closure);                      \
239 }
240
241 #  define FETCHME_GA(closure)           (((globalAddr **)(closure))[FETCHME_GA_LOCN])
242
243 EXTFUN(FetchMe_entry);
244 EXTDATA_RO(FetchMe_info);
245
246 \end{code}
247
248 %************************************************************************
249 %*                                                                      *
250 \subsubsection[BlockedFetch-closures]{@BlockedFetch@ heap objects (`closures')}
251 %*                                                                      *
252 %************************************************************************
253
254 @BlockedFetch@s are inbound fetch messages blocked on local closures.
255 They arise as entries in a local blocking queue when a fetch has been
256 received for a local black hole.  When awakened, we look at their
257 contents to figure out where to send a resume.
258
259 A @BlockedFetch@ closure has the form:
260
261 \begin{onlylatex}
262 \begin{center}
263 \end{onlylatex}
264 \begin{tabular}{||l|l|l||}\hline
265 \tr{BF_info} & link & node & gtid & slot & weight \\ \hline
266 \end{tabular}
267 \begin{onlylatex}
268 \end{center}
269 \end{onlylatex}
270
271 \begin{code}
272 #  define BF_VHS                            (GC_MUT_RESERVED_WORDS)
273 #  define BF_HS                     (FIXED_HS + BF_VHS)
274   
275 #  define BF_LINK_LOCN              (BF_HS)
276 #  define BF_NODE_LOCN              (BF_HS + 1)
277 #  define BF_GTID_LOCN              (BF_HS + 2)
278 #  define BF_SLOT_LOCN              (BF_HS + 3)
279 #  define BF_WEIGHT_LOCN                    (BF_HS + 4)
280   
281 #  define BF_CLOSURE_NoPTRS(closure)    2
282 #  define BF_CLOSURE_NoNONPTRS(closure) 3
283   
284 #  define BF_CLOSURE_SIZE(closure)    (BF_VHS + 5)
285   
286 #  define BF_LINK(closure)          (((PP_)closure)[BF_LINK_LOCN])
287 #  define BF_NODE(closure)          (((PP_)closure)[BF_NODE_LOCN])
288 #  define BF_GTID(closure)          (((P_)closure)[BF_GTID_LOCN])
289 #  define BF_SLOT(closure)          (((P_)closure)[BF_SLOT_LOCN])
290 #  define BF_WEIGHT(closure)        (((P_)closure)[BF_WEIGHT_LOCN])
291   
292 #  define BF_CLOSURE_PTR(closure, no) (((P_)(closure))[BF_HS + (no) - 1])
293
294 /* std start-filling-in macro: */
295 #  define SET_BF_HDR(closure,infolbl,cc)        \
296 { SET_FIXED_HDR(closure,infolbl,cc);            \
297   SET_MUT_RESERVED_WORDS(closure);              \
298 }
299
300 EXTFUN(BF_entry);
301 EXTDATA_RO(BF_info);
302
303 \end{code}
304
305 %************************************************************************
306 %*                                                                      *
307 \subsubsection[FMBQ-closures]{@FMBQ@ (FetchMe with blocking queue) heap objects (`closures')}
308 %*                                                                      *
309 %************************************************************************
310
311 FetchMe's with blocking queues are @Fetchme@ nodes which have been entered
312 (and therefore a fetch has been sent), but for which we have not yet received 
313 a @Resume@ message.  They look just like normal blocking queues, but have
314 a distinguished info pointer.
315
316 \begin{code}
317 #  define FMBQ_VHS                      BQ_VHS
318 #  define FMBQ_HS                               BQ_HS
319   
320 #  define FMBQ_CLOSURE_SIZE(closure)    BQ_CLOSURE_SIZE(closure)
321 #  define FMBQ_CLOSURE_NoPTRS(closure)  BQ_CLOSURE_NoPTRS(closure)
322 #  define FMBQ_CLOSURE_NoNONPTRS(closure)       BQ_CLOSURE_NoNONPTRS(closure)
323 #  define FMBQ_CLOSURE_PTR(closure, no) BQ_CLOSURE_PTR(closure, no)
324   
325 #  define FMBQ_ENTRIES(closure)         BQ_ENTRIES(closure)
326 #  define FMBQ_LINK(closure)            BQ_LINK(closure)
327
328 EXTFUN(FMBQ_entry);
329 EXTDATA_RO(FMBQ_info);
330 \end{code}
331
332 %************************************************************************
333 %*                                                                      *
334 \subsection[parallel-info-tables]{Special parallel-only info-table stuff}
335 %*                                                                      *
336 %************************************************************************
337
338 %************************************************************************
339 %*                                                                      *
340 \subsubsection[FETCHME_ITBL]{@FETCHME_ITBL@}
341 %*                                                                      *
342 %************************************************************************
343
344 ToDo: delete FetchMe CAT (because we don't profile and parallelize at
345 the same time...)  Even better...set things up so that we can profile
346 and parallelize at the same time!
347
348 \begin{code}
349
350 #  define FETCHME_ITBL(itbl_name,entry_code)                    \
351     CAT_DECLARE(FetchMe,INTERNAL_KIND,"FetchMe","<FetchMe>")    \
352     EXTFUN(entry_code);                                         \
353     EXTDATA_RO(MK_REP_LBL(FetchMe,,));                          \
354     const W_ itbl_name[] = {                                    \
355         (W_) entry_code                                         \
356         ,(W_) INFO_OTHER_TAG                                    \
357         ,(W_) MK_REP_REF(FetchMe,,)                             \
358         INCLUDE_PROFILING_INFO(FetchMe)                         \
359     }
360
361 #  define FETCHME_RTBL()                                        \
362     const W_ MK_REP_LBL(FetchMe,,)[] = {                        \
363         INCLUDE_TYPE_INFO(FETCHME)                              \
364         INCLUDE_SIZE_INFO(MIN_UPD_SIZE, 0L)                     \
365         INCLUDE_PAR_INFO                                        \
366         INCLUDE_COPYING_INFO(_Evacuate_FetchMe,_Scavenge_FetchMe) \
367         INCLUDE_COMPACTING_INFO(_ScanLink_FetchMe,_PRStart_FetchMe,_ScanMove_FetchMe,_PRIn_Error) \
368     }
369
370 \end{code}
371
372 %************************************************************************
373 %*                                                                      *
374 \subsubsection[BF_ITBL]{@BF_ITBL@}
375 %*                                                                      *
376 %************************************************************************
377
378 The special info table used for thread state objects (BlockedFetchs).
379
380 \begin{code}
381
382 #  define BF_ITBL()                                 \
383     CAT_DECLARE(BF,INTERNAL_KIND,"BlockedFetch","<BlockedFetch>")    \
384     EXTFUN(BF_entry);                       \
385     EXTDATA_RO(MK_REP_LBL(BF,,));                   \
386     const W_ BF_info[] = {                  \
387         (W_) BF_entry                       \
388         ,(W_) INFO_OTHER_TAG                        \
389         ,(W_) MK_REP_REF(BF,,)              \
390         INCLUDE_PROFILING_INFO(BF)          \
391         }
392
393 #  define BF_RTBL() \
394     const W_ MK_REP_LBL(BF,,)[] = { \
395         INCLUDE_TYPE_INFO(BF)                           \
396         INCLUDE_SIZE_INFO(BF_CLOSURE_SIZE(dummy),BF_CLOSURE_NoPTRS(dummy))      \
397         INCLUDE_PAR_INFO                                        \
398         INCLUDE_COPYING_INFO(_Evacuate_BF,_Scavenge_BF)         \
399         INCLUDE_COMPACTING_INFO(_ScanLink_BF,_PRStart_BF,_ScanMove_BF,_PRIn_BF) \
400         }
401
402 \end{code}
403
404 %************************************************************************
405 %*                                                                      *
406 \subsubsection[FMBQ_ITBL]{@FMBQ_ITBL@}
407 %*                                                                      *
408 %************************************************************************
409
410 Special info-table for local blocking queues.
411
412 \begin{code}
413 #  define FMBQ_ITBL()                           \
414     CAT_DECLARE(FMBQ,INTERNAL_KIND,"FMBQ","<FMBQ>")     \
415     EXTFUN(FMBQ_entry);                         \
416     EXTDATA_RO(MK_REP_LBL(FMBQ,,));             \
417     const W_ FMBQ_info[] = {                    \
418         (W_) FMBQ_entry                         \
419         ,(W_) INFO_OTHER_TAG                    \
420         ,(W_) MK_REP_REF(FMBQ,,)                \
421         INCLUDE_PROFILING_INFO(FMBQ)            \
422     }
423
424 #  define FMBQ_RTBL() \
425     const W_ MK_REP_LBL(FMBQ,,)[] = {                           \
426         INCLUDE_TYPE_INFO(FMBQ)                                 \
427         INCLUDE_SIZE_INFO(MIN_UPD_SIZE,INFO_UNUSED)             \
428         INCLUDE_PAR_INFO                                        \
429         INCLUDE_COPYING_INFO(_Evacuate_BQ,_Scavenge_BQ)         \
430         SPEC_COMPACTING_INFO(_ScanLink_BQ,_PRStart_BQ,_ScanMove_BQ,_PRIn_BQ) \
431     }
432
433 \end{code}
434
435 %************************************************************************
436 %*                                                                      *
437 \subsection[parallel-spark-pool-defs]{Parallel-only Spark pool definitions}
438 %*                                                                      *
439 %************************************************************************
440
441 \begin{code}
442 #  ifdef GRAN
443 #   define HAVE_SPARK ((PendingSparksHd[REQUIRED_POOL] != Nil_closure) ||       \
444                     (PendingSparksHd[ADVISORY_POOL] != Nil_closure))
445 #  else
446 #   define HAVE_SPARK ((PendingSparksHd[REQUIRED_POOL] < PendingSparksTl[REQUIRED_POOL]) \
447                 ||  (PendingSparksHd[ADVISORY_POOL] < PendingSparksTl[ADVISORY_POOL]))
448 #  endif
449
450 #  define HAVE_WORK     (RUNNING_THREAD || HAVE_SPARK)
451 #  define RUNNING_THREAD  (CurrentTSO != NULL)
452 \end{code}
453
454 %************************************************************************
455 %*                                                                      *
456 \subsection[parallel-pack-defs]{Parallel-only Packing definitions}
457 %*                                                                      *
458 %************************************************************************
459
460
461 Symbolic constants for the packing code.
462
463 This constant defines how many words of data we can pack into a single
464 packet in the parallel (GUM) system.
465
466 \begin{code}
467 #  ifdef GUM
468 P_      PackNearbyGraph PROTO((P_ closure,W_ *size));
469 P_      PackTSO PROTO((P_ tso, W_ *size));
470 P_      PackStkO PROTO((P_ stko, W_ *size));
471 P_      AllocateHeap PROTO((W_ size)); /* Doesn't belong */
472
473 P_      get_closure_info PROTO((P_ closure, W_ *size, W_ *ptrs, W_ *nonptrs, W_ *vhs));
474
475 rtsBool isOffset PROTO((globalAddr *ga)),
476         isFixed PROTO((globalAddr *ga));
477
478 void    InitClosureQueue (STG_NO_ARGS);
479 P_      DeQueueClosure(STG_NO_ARGS);
480 void    QueueClosure PROTO((P_ closure));
481 rtsBool QueueEmpty(STG_NO_ARGS);
482 void    PrintPacket PROTO((P_ buffer));
483 void    doGlobalGC(STG_NO_ARGS);
484
485 P_ UnpackGraph PROTO((W_ *buffer, globalAddr **gamap, W_ *nGAs));
486 #  endif
487
488 #  define PACK_BUFFER_SIZE      1024
489 #  define PACK_HEAP_REQUIRED  \
490     ((PACK_BUFFER_SIZE - PACK_HDR_SIZE) / (PACK_GA_SIZE + _FHS) * (SPEC_HS + 2))
491
492 \end{code}
493
494 \begin{code}
495 #  define PACK_GA_SIZE  3       /* Size of a packed GA in words */
496                                 /* Size of a packed fetch-me in words */
497 #  define PACK_FETCHME_SIZE (PACK_GA_SIZE + FIXED_HS)
498
499 #  define PACK_HDR_SIZE 1       /* Words of header in a packet */
500
501 #  define PACK_PLC_SIZE 2       /* Size of a packed PLC in words */
502   
503 #  define MAX_GAS       (PACK_BUFFER_SIZE / PACK_GA_SIZE)
504
505 \end{code}
506 End multi-slurp protection:
507 \begin{code}
508 # endif /* yes, it is PARallel */
509 #endif /* it was GRAN or PARallel */
510
511 #endif /* Parallel_H */
512 \end{code}