1 /* ---------------------------------------------------------------------------
2 Time-stamp: <Mon Mar 27 2000 17:10:57 Stardate: [-30]4568.37 hwloidl>
3 $Id: Global.c,v 1.3 2000/03/31 03:09:37 hwloidl Exp $
5 (c) The AQUA/Parade Projects, Glasgow University, 1995
6 The GdH/APART 624 Projects, Heriot-Watt University, Edinburgh, 1999
8 Global Address Manipulation.
10 The GALA and LAGA tables for mapping global addresses to local addresses
11 (i.e. heap pointers) are defined here. We use the generic hash tables
13 ------------------------------------------------------------------------- */
15 #ifdef PAR /* whole file */
19 //* Global tables and lists::
20 //* Fcts on GALA tables::
21 //* Interface to taskId-PE table::
22 //* Interface to LAGA table::
23 //* Interface to GALA table::
24 //* GC functions for GALA tables::
28 //@node Includes, Global tables and lists, Global Address Manipulation, Global Address Manipulation
29 //@subsection Includes
36 #include "ParallelRts.h"
42 @globalAddr@ structures are allocated in chunks to reduce malloc overhead.
45 //@node Global tables and lists, Fcts on GALA tables, Includes, Global Address Manipulation
46 //@subsection Global tables and lists
56 //@node Free lists, Hash tables, Global tables and lists, Global tables and lists
57 //@subsubsection Free lists
59 /* Free list of GALA entries */
60 GALA *freeGALAList = NULL;
62 /* Number of globalAddr cells to allocate in one go */
63 #define GCHUNK (1024 * sizeof(StgWord) / sizeof(GALA))
65 /* Free list of indirections */
67 //@cindex nextIndirection
68 static StgInt nextIndirection = 0;
69 //@cindex freeIndirections
70 GALA *freeIndirections = NULL;
72 /* The list of live indirections has to be marked for GC (see makeGlobal) */
73 //@cindex liveIndirections
74 GALA *liveIndirections = NULL;
76 /* The list of remote indirections has to be marked for GC (see setRemoteGA) */
77 //@cindex liveRemoteGAs
78 GALA *liveRemoteGAs = NULL;
80 //@node Hash tables, , Free lists, Global tables and lists
81 //@subsubsection Hash tables
83 /* Mapping global task ids PEs */
84 //@cindex taskIDtoPEtable
85 HashTable *taskIDtoPEtable = NULL;
87 static int nextPE = 0;
89 /* LAGA table: StgClosure* -> globalAddr*
90 (Remember: globalAddr = (GlobalTaskId, Slot, Weight))
91 Mapping local to global addresses (see interface below)
94 //@cindex LAtoGALAtable
95 HashTable *LAtoGALAtable = NULL;
97 /* GALA table: globalAddr* -> StgClosure*
98 (Remember: globalAddr = (GlobalTaskId, Slot, Weight))
99 Mapping global to local addresses (see interface below)
102 //@cindex pGAtoGALAtable
103 HashTable *pGAtoGALAtable = NULL;
105 //@node Fcts on GALA tables, Interface to taskId-PE table, Global tables and lists, Global Address Manipulation
106 //@subsection Fcts on GALA tables
114 if ((gl = freeGALAList) != NULL) {
116 ASSERT(gl->ga.weight==0xdead0add);
117 ASSERT(gl->la==0xdead00aa));
118 freeGALAList = gl->next;
120 gl = (GALA *) stgMallocBytes(GCHUNK * sizeof(GALA), "allocGALA");
122 freeGALAList = gl + 1;
123 for (p = freeGALAList; p < gl + GCHUNK - 1; p++) {
126 p->ga.weight=0xdead0add;
129 /* last elem in the new block has NULL pointer in link field */
132 p->ga.weight=0xdead0add;
136 gl->ga.weight=0xdead0add;
141 //@node Interface to taskId-PE table, Interface to LAGA table, Fcts on GALA tables, Global Address Manipulation
142 //@subsection Interface to taskId-PE table
145 We don't really like GLOBAL_TASK_ID, so we keep a table of TASK_ID to
146 PE mappings. The idea is that a PE identifier will fit in 16 bits, whereas
152 taskIDtoPE(GlobalTaskId gtid)
154 return (PEs) lookupHashTable(taskIDtoPEtable, gtid);
157 //@cindex registerTask
165 insertHashTable(taskIDtoPEtable, gtid, (void *) (StgWord) nextPE++);
168 //@node Interface to LAGA table, Interface to GALA table, Interface to taskId-PE table, Global Address Manipulation
169 //@subsection Interface to LAGA table
172 The local address to global address mapping returns a globalAddr structure
173 (pe task id, slot, weight) for any closure in the local heap which has a
174 global identity. Such closures may be copies of normal form objects with
175 a remote `master' location, @FetchMe@ nodes referencing remote objects, or
176 globally visible objects in the local heap (for which we are the master).
186 /* We never look for GA's on indirections. -- unknown hacker
187 Well, in fact at the moment we do in the new RTS. -- HWL
188 ToDo: unwind INDs when entering them into the hash table
190 ASSERT(IS_INDIRECTION(addr) == NULL);
192 if ((gala = lookupHashTable(LAtoGALAtable, (StgWord) addr)) == NULL)
198 //@node Interface to GALA table, GC functions for GALA tables, Interface to LAGA table, Global Address Manipulation
199 //@subsection Interface to GALA table
202 We also manage a mapping of global addresses to local addresses, so that
203 we can ``common up'' multiple references to the same object as they arrive
204 in data packets from remote PEs.
206 The global address to local address mapping is actually managed via a
207 ``packed global address'' to GALA hash table. The packed global
208 address takes the interesting part of the @globalAddr@ structure
209 (i.e. the pe and slot fields) and packs them into a single word
210 suitable for hashing.
218 StgWord pga = PackGA(taskIDtoPE(ga->payload.gc.gtid), ga->payload.gc.slot);
221 if ((gala = (GALA *) lookupHashTable(pGAtoGALAtable, pga)) == NULL)
225 * Bypass any indirections when returning a local closure to
226 * the caller. Note that we do not short-circuit the entry in
227 * the GALA tables right now, because we would have to do a
228 * hash table delete and insert in the LAtoGALAtable to keep
229 * that table up-to-date for preferred GALA pairs. That's
230 * probably a bit expensive.
232 return UNWIND_IND((StgClosure *)(gala->la));
236 /* ga becomes non-preferred (e.g. due to CommonUp) */
241 StgWord pga = PackGA(taskIDtoPE(ga->payload.gc.gtid), ga->payload.gc.slot);
244 gala = (GALA *) lookupHashTable(pGAtoGALAtable, pga);
246 ASSERT(gala->preferred==rtsTrue);
247 gala->preferred==rtsFalse;
251 External references to our globally-visible closures are managed through an
252 indirection table. The idea is that the closure may move about as the result
253 of local garbage collections, but its global identity is determined by its
254 slot in the indirection table, which never changes.
256 The indirection table is maintained implicitly as part of the global
257 address to local address table. We need only keep track of the
258 highest numbered indirection index allocated so far, along with a free
259 list of lower numbered indices no longer in use.
263 Allocate an indirection slot for the closure currently at address @addr@.
266 //@cindex allocIndirection
268 allocIndirection(StgClosure *closure)
272 if ((gala = freeIndirections) != NULL) {
274 ASSERT(gala->ga.weight==0xdead0add);
275 ASSERT(gala->la==0xdead00aa));
276 freeIndirections = gala->next;
280 ASSERT(gala->ga.weight==0xdead0add);
281 ASSERT(gala->la==0xdead00aa));
282 gala->ga.payload.gc.gtid = mytid;
283 gala->ga.payload.gc.slot = nextIndirection++;
285 gala->ga.weight = MAX_GA_WEIGHT;
288 gala->next=0xcccccccc);
293 This is only used for sanity checking (see LOOKS_LIKE_SLOT)
296 highest_slot (void) { return nextIndirection; }
299 Make a local closure globally visible.
301 Called from: GlobaliseAndPackGA
303 closure ... closure to be made visible
304 preferred ... should the new GA become the preferred one (normalle=y true)
306 Allocate a GALA structure and add it to the (logical) Indirections table,
307 by inserting it into the LAtoGALAtable hash table and putting it onto the
308 liveIndirections list (only if it is preferred).
310 We have to allocate an indirection slot for it, and update both the local
311 address to global address and global address to local address maps.
316 makeGlobal(closure, preferred)
320 /* check whether we already have a GA for this local closure */
321 GALA *oldGALA = lookupHashTable(LAtoGALAtable, (StgWord) closure);
322 /* create an entry in the LAGA table */
323 GALA *newGALA = allocIndirection((StgPtr)closure);
324 StgWord pga = PackGA(thisPE, newGALA->ga.payload.gc.slot);
327 ASSERT(newGALA->next==0xcccccccc););
328 // ASSERT(HEAP_ALLOCED(closure)); // check that closure might point into the heap; might be static, though
329 ASSERT(GALAlookup(&(newGALA->ga)) == NULL);
331 newGALA->la = closure;
332 newGALA->preferred = preferred;
335 /* The new GA is now the preferred GA for the LA */
336 if (oldGALA != NULL) {
337 oldGALA->preferred = rtsFalse;
338 (void) removeHashTable(LAtoGALAtable, (StgWord) closure, (void *) oldGALA);
340 insertHashTable(LAtoGALAtable, (StgWord) closure, (void *) newGALA);
343 ASSERT(!isOnLiveIndTable(&(newGALA->ga)));
344 /* put the new GALA entry on the list of live indirections */
345 newGALA->next = liveIndirections;
346 liveIndirections = newGALA;
348 insertHashTable(pGAtoGALAtable, pga, (void *) newGALA);
350 return &(newGALA->ga);
354 Assign an existing remote global address to an existing closure.
356 Called from: Unpack in Pack.c
358 local_closure ... a closure that has just been unpacked
359 remote_ga ... the GA that came with it, ie. the name under which the
360 closure is known while being transferred
361 preferred ... should the new GA become the preferred one (normalle=y true)
363 Allocate a GALA structure and add it to the (logical) RemoteGA table,
364 by inserting it into the LAtoGALAtable hash table and putting it onto the
365 liveRemoteGAs list (only if it is preferred).
367 We do not retain the @globalAddr@ structure that's passed in as an argument,
368 so it can be a static in the calling routine.
371 //@cindex setRemoteGA
373 setRemoteGA(local_closure, remote_ga, preferred)
374 StgClosure *local_closure;
375 globalAddr *remote_ga;
378 /* old entry ie the one with the GA generated when sending off the closure */
379 GALA *oldGALA = lookupHashTable(LAtoGALAtable, (StgWord) local_closure);
380 /* alloc new entry and fill it with contents of the newly arrives GA */
381 GALA *newGALA = allocGALA();
382 StgWord pga = PackGA(taskIDtoPE(remote_ga->payload.gc.gtid),
383 remote_ga->payload.gc.slot);
385 ASSERT(remote_ga->payload.gc.gtid != mytid);
386 ASSERT(remote_ga->weight > 0);
387 ASSERT(GALAlookup(remote_ga) == NULL);
389 newGALA->ga = *remote_ga;
390 newGALA->la = local_closure;
391 newGALA->preferred = preferred;
394 /* The new GA is now the preferred GA for the LA */
395 if (oldGALA != NULL) {
396 oldGALA->preferred = rtsFalse;
397 (void) removeHashTable(LAtoGALAtable, (StgWord) local_closure, (void *) oldGALA);
399 insertHashTable(LAtoGALAtable, (StgWord) local_closure, (void *) newGALA);
402 ASSERT(!isOnRemoteGATable(&(newGALA->ga)));
403 /* add new entry to the (logical) RemoteGA table */
404 newGALA->next = liveRemoteGAs;
405 liveRemoteGAs = newGALA;
407 insertHashTable(pGAtoGALAtable, pga, (void *) newGALA);
410 The weight carried by the incoming closure is transferred to the newGALA
411 entry (via the structure assign above). Therefore, we have to give back
412 the weight to the GA on the other processor, because that indirection is
415 remote_ga->weight = 0;
416 return &(newGALA->ga);
420 Give me a bit of weight to give away on a new reference to a particular
421 global address. If we run down to nothing, we have to assign a new GA.
424 //@cindex splitWeight
427 splitWeight(to, from)
428 globalAddr *to, *from;
430 /* Make sure we have enough weight to split */
431 if (from->weight!=MAX_GA_WEIGHT && from->weight<=3) // fixed by UK in Eden implementation
432 from = makeGlobal(GALAlookup(from), rtsTrue);
434 to->payload = from->payload;
436 if (from->weight == MAX_GA_WEIGHT)
437 to->weight = 1L << (BITS_IN(unsigned) - 1);
439 to->weight = from->weight / 2;
441 from->weight -= to->weight;
445 splitWeight(to, from)
446 globalAddr *to, *from;
448 /* Make sure we have enough weight to split */
449 /* Splitting at 2 needed, as weight 1 is not legal in packets (UK+KH) */
451 if (from->weight / 2 <= 2) /* old: weight== 1 (UK) */
452 from = makeGlobal(GALAlookup(from), rtsTrue);
454 to->payload = from->payload;
456 if (from->weight <= 1) /* old == 0 (UK) */
457 to->weight = 1L << (BITS_IN(unsigned) - 1);
459 to->weight = from->weight / 2;
461 from->weight -= to->weight;
465 Here, I am returning a bit of weight that a remote PE no longer needs.
473 StgWord pga = PackGA(taskIDtoPE(ga->payload.gc.gtid), ga->payload.gc.slot);
474 GALA *gala = (GALA *) lookupHashTable(pGAtoGALAtable, pga);
477 fprintf(stderr, "@* Adding weight %x to ", ga->weight);
478 printGA(&(gala->ga));
479 fputc('\n', stderr));
481 gala->ga.weight += ga->weight;
488 Initialize all of the global address structures: the task ID to PE id
489 map, the local address to global address map, the global address to
490 local address map, and the indirection table.
493 //@cindex initGAtables
497 taskIDtoPEtable = allocHashTable();
498 LAtoGALAtable = allocHashTable();
499 pGAtoGALAtable = allocHashTable();
501 stickyClosureTable = allocHashTable();
511 int pe_shift = (BITS_IN(StgWord)*3)/4;
512 int pe_bits = BITS_IN(StgWord) - pe_shift;
514 if ( pe_bits < 8 || slot >= (1L << pe_shift) ) { /* big trouble */
516 fprintf(stderr, "PackGA: slot# too big (%d) or not enough pe_bits (%d)\n",
518 stg_exit(EXIT_FAILURE);
521 return((((StgWord)(pe)) << pe_shift) | ((StgWord)(slot)));
523 /* the idea is to use 3/4 of the bits (e.g., 24) for indirection-
524 table "slot", and 1/4 for the pe# (e.g., 8).
526 We check for too many bits in "slot", and double-check (at
527 compile-time?) that we have enough bits for "pe". We *don't*
528 check for too many bits in "pe", because SysMan enforces a
529 MAX_PEs limit at the very very beginning.
535 //@node GC functions for GALA tables, Debugging routines, Interface to GALA table, Global Address Manipulation
536 //@subsection GC functions for GALA tables
539 When we do a copying collection, we want to evacuate all of the local
540 entries in the GALA table for which there are outstanding remote
541 pointers (i.e. for which the weight is not MAX_GA_WEIGHT.)
542 This routine has to be run BEFORE doing the GC proper (it's a
543 ``mark roots'' thing).
545 //@cindex markLocalGAs
547 markLocalGAs(rtsBool full)
552 StgPtr old_la, new_la;
553 nat n=0, m=0; // debugging only
556 belch("@@%%%% markLocalGAs: Marking LIVE INDIRECTIONS in GALA table starting with GALA at %p\n",
560 for (gala = liveIndirections, m=0; gala != NULL; gala = next, m++) {
563 printGA(&(gala->ga));
564 fprintf(stderr, ";@ %d: LA: %p (%s) ",
565 m, gala->la, info_type(gala->la)));
568 ASSERT(gala->ga.payload.gc.gtid == mytid); /* it's supposed to be local */
569 if (gala->ga.weight != MAX_GA_WEIGHT) {
570 /* Remote references exist, so we must evacuate the local closure */
571 if (get_itbl((StgClosure *)old_la)->type == EVACUATED) {
572 /* somebody else already evacuated this closure */
573 new_la = ((StgEvacuated *)old_la)->evacuee;
575 belch(" already evacuated to %p", new_la));
578 /* unwind any indirections we find */
579 StgClosure *foo = UNWIND_IND((StgClosure *)old_la) ; // debugging only
580 //ASSERT(HEAP_ALLOCED(foo));
583 new_la = MarkRoot(foo); // or just evacuate(old_ga)
585 belch(" evacuated %p to %p", foo, new_la));
586 //ASSERT(Bdescr(new_la)->evacuated);
588 new_la = MarkRoot(old_la); // or just evacuate(old_ga)
590 belch(" evacuated %p to %p", old_la, new_la));
595 /* remove old LA and replace with new LA */
596 if (!full && gala->preferred && new_la != old_la) {
598 ASSERT(lookupHashTable(LAtoGALAtable, (StgWord)old_la));
599 (void) removeHashTable(LAtoGALAtable, (StgWord) old_la, (void *) gala);
600 if ((q = lookupHashTable(LAtoGALAtable, (StgWord) new_la))!=NULL) {
601 if (q->preferred && gala->preferred) {
602 q->preferred = rtsFalse;
604 fprintf(stderr, "@@## found hash entry for closure %p (%s): deprecated GA ",
605 new_la, info_type(new_la));
607 fputc('\n', stderr));
610 insertHashTable(LAtoGALAtable, (StgWord) new_la, (void *) gala);
613 belch("__## Hash table update (%p --> %p): ",
620 /* Since we have all of the weight, this GA is no longer needed */
621 StgWord pga = PackGA(thisPE, gala->ga.payload.gc.slot);
624 belch("@@!! Freeing slot %d",
625 gala->ga.payload.gc.slot));
626 /* put gala on free indirections list */
627 gala->next = freeIndirections;
628 freeIndirections = gala;
629 (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala);
630 if (!full && gala->preferred)
631 (void) removeHashTable(LAtoGALAtable, (W_) gala->la, (void *) gala);
634 gala->ga.weight = 0xdead0add;
635 gala->la = (StgClosure *) 0xdead00aa);
638 liveIndirections = prev; /* list has been reversed during the marking */
641 belch("@@%%%% markLocalGAs: %d of %d GALAs marked on PE %x",
646 Traverse the GALA table: for every live remote GA check whether it has been
647 touched during GC; if not it is not needed locally and we can free the
648 closure (i.e. let go of its heap space and send a free message to the
650 This routine has to be run AFTER doing the GC proper.
653 rebuildGAtables(rtsBool full)
658 StgClosure *closure, *last, *new_closure;
660 prepareFreeMsgBuffers();
663 belch("@@%%%% rebuildGAtables: rebuilding LIVE REMOTE GAs in GALA table starting with GALA at %p\n",
666 for (gala = liveRemoteGAs, prev = NULL; gala != NULL; gala = next) {
668 printGA(&(gala->ga)));
670 ASSERT(gala->ga.payload.gc.gtid != mytid); /* it's supposed to be remote */
672 closure = (StgClosure *) (gala->la);
674 fprintf(stderr, " %p (%s) ",
675 (StgClosure *)closure, info_type(closure)));
677 if (!full && gala->preferred)
678 (void) removeHashTable(LAtoGALAtable, (StgWord) gala->la, (void *) gala);
680 /* Follow indirection chains to the end, just in case */
681 // should conform with unwinding in markLocalGAs
682 closure = UNWIND_IND(closure);
685 If closure has been evacuated it is live; otherwise it's dead and we
686 can nuke the GA attached to it in the LAGA table.
687 This approach also drops global aliases for PLCs.
690 if (get_itbl(closure)->type == EVACUATED) {
691 closure = ((StgEvacuated *)closure)->evacuee;
693 fprintf(stderr, " EVAC %p (%s)\n",
694 closure, info_type(closure)));
696 /* closure is not alive any more, thus remove GA and send free msg */
697 int pe = taskIDtoPE(gala->ga.payload.gc.gtid);
698 StgWord pga = PackGA(pe, gala->ga.payload.gc.slot);
700 /* check that the block containing this closure is not in to-space */
701 //ASSERT(Bdescr(closure)->evacuated==0);
703 fprintf(stderr, " !EVAC %p (%s); sending free to PE %d\n",
704 closure, info_type(closure), pe));
706 (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala);
707 freeRemoteGA(pe, &(gala->ga));
708 gala->next = freeGALAList;
711 gala->ga.weight = 0xdead0add;
712 gala->la = 0xdead00aa);
716 if (!full && gala->preferred) {
718 if ((q = lookupHashTable(LAtoGALAtable, (StgWord) gala->la))!=NULL) {
719 if (q->preferred && gala->preferred) {
720 q->preferred = rtsFalse;
722 fprintf(stderr, "@@## found hash entry for closure %p (%s): deprecated GA ",
723 gala->la, info_type(gala->la));
725 fputc('\n', stderr));
728 insertHashTable(LAtoGALAtable, (StgWord) gala->la, (void *) gala);
735 liveRemoteGAs = prev; /* list is reversed during marking */
737 /* If we have any remaining FREE messages to send off, do so now */
742 checkFreeIndirectionsList());
748 belch("@#%%%% rebuildGAtables: After ReBuilding GALA table starting with GALA at %p",
754 Rebuild the LA->GA table, assuming that the addresses in the GALAs are
756 A word on the lookupHashTable check in both loops:
757 After GC we may end up with 2 preferred GAs for the same LA! For example,
758 if we received a closure whose GA already exists on this PE we CommonUp
759 both closures, making one an indirection to the other. Before GC everything
760 is fine: one preferred GA refers to the IND, the other preferred GA refers
761 to the closure it points to. After GC, however, we have short cutted the
762 IND and suddenly we have 2 preferred GAs for the same closure. We detect
763 this case in the loop below and deprecate one GA, so that we always just
764 have one preferred GA per LA.
767 //@cindex rebuildLAGAtable
769 rebuildLAGAtable(void)
772 nat n=0, m=0; // debugging
774 /* The old LA->GA table is worthless */
775 freeHashTable(LAtoGALAtable, NULL);
776 LAtoGALAtable = allocHashTable();
779 belch("@@%%%% rebuildLAGAtable: new LAGA table at %p",
782 for (gala = liveIndirections; gala != NULL; gala = gala->next) {
784 if (gala->preferred) {
786 if (q = lookupHashTable(LAtoGALAtable, (StgWord) gala->la)) {
787 if (q->preferred && gala->preferred) {
788 /* this deprecates q (see also GALAdeprecate) */
789 q->preferred = rtsFalse;
790 (void) removeHashTable(LAtoGALAtable, (StgWord) gala->la, (void *)q);
792 fprintf(stderr, "@@## found hash entry for closure %p (%s): deprecated GA ",
793 gala->la, info_type(gala->la));
795 fputc('\n', stderr));
798 insertHashTable(LAtoGALAtable, (StgWord) gala->la, (void *) gala);
802 for (gala = liveRemoteGAs; gala != NULL; gala = gala->next) {
804 if (gala->preferred) {
806 if (q = lookupHashTable(LAtoGALAtable, (StgWord) gala->la)) {
807 if (q->preferred && gala->preferred) {
808 /* this deprecates q (see also GALAdeprecate) */
809 q->preferred = rtsFalse;
810 (void) removeHashTable(LAtoGALAtable, (StgWord) gala->la, (void *)q);
812 fprintf(stderr, "@@## found hash entry for closure %p (%s): deprecated GA ",
813 gala->la, info_type(gala->la));
815 fputc('\n', stderr));
818 insertHashTable(LAtoGALAtable, (StgWord) gala->la, (void *) gala);
823 belch("@@%%%% rebuildLAGAtable: inserted %d entries from liveIndirections and %d entries from liveRemoteGAs",
827 //@node Debugging routines, Index, GC functions for GALA tables, Global Address Manipulation
828 //@subsection Debugging routines
832 printGA (globalAddr *ga)
834 fprintf(stderr, "((%x, %d, %x))",
842 printGALA (GALA *gala)
844 printGA(&(gala->ga));
845 fprintf(stderr, " -> %p (%s)", (StgPtr)gala->la, info_type(gala->la));
846 fprintf(stderr, " %s", (gala->preferred) ? "PREF" : "____");
850 Printing the LA->GA table.
853 //@cindex printLiveIndTable
855 printLiveIndTable(void)
858 nat n=0; // debugging
860 belch("@@%%%%:: logical LiveIndTable (%p) (liveIndirections=%p):",
861 LAtoGALAtable, liveIndirections);
863 for (gala = liveIndirections; gala != NULL; gala = gala->next) {
866 /* check whether this gala->la is hashed into the LAGA table */
867 q = lookupHashTable(LAtoGALAtable, (StgWord)(gala->la));
868 fprintf(stderr, "\t%s\n", (q==NULL) ? "...." : (q==gala) ? "====" : "####");
869 //ASSERT(lookupHashTable(LAtoGALAtable, (StgWord)(gala->la)));
871 belch("@@%%%%:: %d live indirections",
876 printRemoteGATable(void)
879 nat m=0; // debugging
881 belch("@@%%%%:: logical RemoteGATable (%p) (liveRemoteGAs=%p):",
882 LAtoGALAtable, liveRemoteGAs);
884 for (gala = liveRemoteGAs; gala != NULL; gala = gala->next) {
887 /* check whether this gala->la is hashed into the LAGA table */
888 q = lookupHashTable(LAtoGALAtable, (StgWord)(gala->la));
889 fprintf(stderr, "\t%s\n", (q==NULL) ? "...." : (q==gala) ? "====" : "####");
890 // ASSERT(lookupHashTable(LAtoGALAtable, (StgWord)(gala->la)));
892 belch("@@%%%%:: %d remote GAs",
896 //@cindex printLAGAtable
900 belch("@@%%: LAGAtable (%p) with liveIndirections=%p, liveRemoteGAs=%p:",
901 LAtoGALAtable, liveIndirections, liveRemoteGAs);
904 printRemoteGATable();
908 Check whether a GA is already in a list.
911 isOnLiveIndTable(globalAddr *ga)
915 for (gala = liveIndirections; gala != NULL; gala = gala->next)
916 if (gala->ga.weight==ga->weight &&
917 gala->ga.payload.gc.slot==ga->payload.gc.slot &&
918 gala->ga.payload.gc.gtid==ga->payload.gc.gtid)
925 isOnRemoteGATable(globalAddr *ga)
929 for (gala = liveRemoteGAs; gala != NULL; gala = gala->next)
930 if (gala->ga.weight==ga->weight &&
931 gala->ga.payload.gc.slot==ga->payload.gc.slot &&
932 gala->ga.payload.gc.gtid==ga->payload.gc.gtid)
939 Sanity check for free lists.
942 checkFreeGALAList(void) {
945 for (gl=freeGALAList; gl != NULL; gl=gl->next) {
946 ASSERT(gl->ga.weight==0xdead0add);
947 ASSERT(gl->la==0xdead00aa);
952 checkFreeIndirectionsList(void) {
955 for (gl=freeIndirections; gl != NULL; gl=gl->next) {
956 ASSERT(gl->ga.weight==0xdead0add);
957 ASSERT(gl->la==0xdead00aa);
960 #endif /* PAR -- whole file */
962 //@node Index, , Debugging routines, Global Address Manipulation
966 //* DebugPrintLAGAtable:: @cindex\s-+DebugPrintLAGAtable
967 //* GALAlookup:: @cindex\s-+GALAlookup
968 //* LAGAlookup:: @cindex\s-+LAGAlookup
969 //* LAtoGALAtable:: @cindex\s-+LAtoGALAtable
970 //* PackGA:: @cindex\s-+PackGA
971 //* addWeight:: @cindex\s-+addWeight
972 //* allocGALA:: @cindex\s-+allocGALA
973 //* allocIndirection:: @cindex\s-+allocIndirection
974 //* freeIndirections:: @cindex\s-+freeIndirections
975 //* initGAtables:: @cindex\s-+initGAtables
976 //* liveIndirections:: @cindex\s-+liveIndirections
977 //* liveRemoteGAs:: @cindex\s-+liveRemoteGAs
978 //* makeGlobal:: @cindex\s-+makeGlobal
979 //* markLocalGAs:: @cindex\s-+markLocalGAs
980 //* nextIndirection:: @cindex\s-+nextIndirection
981 //* pGAtoGALAtable:: @cindex\s-+pGAtoGALAtable
982 //* printGA:: @cindex\s-+printGA
983 //* printGALA:: @cindex\s-+printGALA
984 //* rebuildLAGAtable:: @cindex\s-+rebuildLAGAtable
985 //* registerTask:: @cindex\s-+registerTask
986 //* setRemoteGA:: @cindex\s-+setRemoteGA
987 //* splitWeight:: @cindex\s-+splitWeight
988 //* taskIDtoPE:: @cindex\s-+taskIDtoPE
989 //* taskIDtoPEtable:: @cindex\s-+taskIDtoPEtable
990 //* thisPE:: @cindex\s-+thisPE