/* ----------------------------------------------------------------------------
- Time-stamp: <Fri Jan 14 2000 09:41:07 Stardate: [-30]4202.01 hwloidl>
- $Id: FetchMe.hc,v 1.4 2000/01/14 16:15:08 simonmar Exp $
+ Time-stamp: <Thu Feb 24 2000 21:31:41 Stardate: [-30]4409.48 hwloidl>
+ $Id: FetchMe.hc,v 1.5 2000/03/31 03:09:37 hwloidl Exp $
Entry code for a FETCH_ME closure
another PE. We issue a fetch message, and wait for the data to be
retrieved.
+ A word on the ptr/nonptr fields in the macros: they are unused at the
+ moment; all closures defined here have constant size (ie. no payload
+ that varies from closure to closure). Therefore, all routines that
+ need to know the size of these closures have to do a sizeofW(StgFetchMe)
+ etc to get the closure size. See get_closure_info(), evacuate() and
+ checkClosure() (using the same fcts for determining the size of the
+ closures would be a good idea; at least it would be a nice step towards
+ making this code bug free).
+
About the difference between std and PAR in returning to the RTS:
in PAR we call RTS functions from within the entry code (see also
BLACKHOLE_entry and friends in StgMiscClosures.hc); therefore, we
//@cindex FETCH_ME_entry
STGFUN(FETCH_ME_entry)
{
+ /*
+ Not needed any more since we call blockThread in the scheduler
+ (via BLOCK_NP(1) which returns with BlockedOnGA
+
extern globalAddr *rga_GLOBAL;
extern globalAddr *lga_GLOBAL;
extern globalAddr fmbqga_GLOBAL;
extern StgClosure *p_GLOBAL;
- /*
globalAddr *rga;
globalAddr *lga;
globalAddr fmbqga;
*/
FB_
- rga_GLOBAL = ((StgFetchMe *)R1.p)->ga;
- ASSERT(rga->payload.gc.gtid != mytid);
-
- /* Turn the FETCH_ME into a FETCH_ME_BQ, and place the current thread
- * on the blocking queue.
- */
- // R1.cl->header.info = FETCH_ME_BQ_info;
- SET_INFO((StgClosure *)R1.cl, &FETCH_ME_BQ_info);
-
- CurrentTSO->link = END_BQ_QUEUE;
- ((StgFetchMeBlockingQueue *)R1.cl)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
-
- /* record onto which closure the current thread is blcoking */
- CurrentTSO->block_info.closure = R1.cl;
- //recordMutable((StgMutClosure *)R1.cl);
- p_GLOBAL = R1.cl;
-
- /* Save the Thread State here, before calling RTS routines below! */
- //BLOCK_NP_NO_JUMP(1);
- SAVE_THREAD_STATE(1);
-
- /* unknown junk... needed? --SDM yes, want to see what's happening -- HWL */
- if (RtsFlags.ParFlags.ParStats.Full) {
- /* Note that CURRENT_TIME may perform an unsafe call */
- //rtsTime now = CURRENT_TIME; /* Now */
- CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
- CurrentTSO->par.fetchcount++;
- /* TSO_QUEUE(CurrentTSO) = Q_FETCHING; */
- CurrentTSO->par.blockedat = CURRENT_TIME;
- /* we are about to send off a FETCH message, so dump a FETCH event */
- /* following should be an STGCALL --SDM */
- DumpRawGranEvent(CURRENT_PROC, taskIDtoPE(rga_GLOBAL->payload.gc.gtid),
- GR_FETCH, CurrentTSO, (StgClosure *)R1.p, 0);
- }
-
- /* Phil T. claims that this was a workaround for a hard-to-find
- * bug, hence I'm leaving it out for now --SDM
- */
- /* Assign a brand-new global address to the newly created FMBQ */
- lga_GLOBAL = makeGlobal(p_GLOBAL, rtsFalse);
- splitWeight(&fmbqga_GLOBAL, lga_GLOBAL);
- ASSERT(fmbqga_GLOBAL.weight == 1L << (BITS_IN(unsigned) - 1));
-
- STGCALL3(sendFetch, rga_GLOBAL, &fmbqga_GLOBAL, 0/*load*/);
-
- // sendFetch now called from processTheRealFetch, to make SDM happy
- //theGlobalFromGA.payload.gc.gtid = rga->payload.gc.gtid;
- //theGlobalFromGA.payload.gc.slot = rga->payload.gc.slot;
- //theGlobalFromGA.weight = rga->weight;
- //theGlobalToGA.payload.gc.gtid = fmbqga.payload.gc.gtid;
- //theGlobalToGA.payload.gc.slot = fmbqga.payload.gc.slot;
- //theGlobalToGA.weight = fmbqga.weight;
-
- // STGCALL6(fprintf,stderr,"%% Fetching %p from remote PE ((%x,%d,%x))\n",R1.p,rga->payload.gc.gtid, rga->payload.gc.slot, rga->weight);
-
- THREAD_RETURN(1); /* back to the scheduler */
- // was: BLOCK_NP(1);
+ /*
+ rga_GLOBAL = ((StgFetchMe *)R1.p)->ga;
+ ASSERT(rga->payload.gc.gtid != mytid);
+ */
+ ASSERT(((StgFetchMe *)R1.p)->ga->payload.gc.gtid != mytid);
+
+ /* Turn the FETCH_ME into a FETCH_ME_BQ, and place the current thread
+ * on the blocking queue.
+ */
+ // R1.cl->header.info = FETCH_ME_BQ_info;
+ SET_INFO((StgClosure *)R1.cl, &FETCH_ME_BQ_info);
+
+ /* Put ourselves on the blocking queue for this black hole */
+ // This is really, really BAD; tmp HACK to remember ga (checked in blockThread)
+ ASSERT(looks_like_ga(((StgFetchMe *)R1.p)->ga));
+ CurrentTSO->link = (StgBlockingQueueElement *)((StgFetchMe *)R1.p)->ga; // END_BQ_QUEUE;
+ ((StgFetchMeBlockingQueue *)R1.cl)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
+
+ /* jot down why and on what closure we are blocked */
+ CurrentTSO->why_blocked = BlockedOnGA;
+ CurrentTSO->block_info.closure = R1.cl;
+ //recordMutable((StgMutClosure *)R1.cl);
+ //p_GLOBAL = R1.cl;
+
+ /* sendFetch etc is now done in blockThread, which is called from the
+ scheduler -- HWL */
+
+ BLOCK_NP(1);
FE_
}
FB_
TICK_ENT_BH();
- /* Put ourselves on the blocking queue for this black hole */
- CurrentTSO->block_info.closure = R1.cl;
+ /* Put ourselves on the blocking queue for this node */
CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
-#if defined(PAR)
- /* Save the Thread State here, before calling RTS routines below! */
- SAVE_THREAD_STATE(1);
-
- if (RtsFlags.ParFlags.ParStats.Full) {
- /* Note that CURRENT_TIME may perform an unsafe call */
- //rtsTime now = CURRENT_TIME; /* Now */
- CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
- CurrentTSO->par.blockcount++;
- CurrentTSO->par.blockedat = CURRENT_TIME;
- DumpRawGranEvent(CURRENT_PROC, thisPE,
- GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
- }
-
- THREAD_RETURN(1); /* back to the scheduler */
-#else
+ /* jot down why and on what closure we are blocked */
+ CurrentTSO->why_blocked = BlockedOnGA_NoSend;
+ CurrentTSO->block_info.closure = R1.cl;
+
/* stg_gen_block is too heavyweight, use a specialised one */
BLOCK_NP(1);
-#endif
FE_
}
globally visible closure i.e. one with a GA. A BLOCKED_FETCH closure
indicates that a TSO on another PE is waiting for the result of this
computation. Thus, when updating the closure, the result has to be sent
- to that PE. The relevant routines handling that are awaken_blocked_queue
+ to that PE. The relevant routines handling that are awakenBlockedQueue
and blockFetch (for putting BLOCKED_FETCH closure into a BQ).
*/
{
FB_
/* see NON_ENTERABLE_ENTRY_CODE in StgMiscClosures.hc */
- DUMP_ERRMSG("BLOCKED_FETCH object entered!\n");
+ STGCALL2(fprintf,stderr,"BLOCKED_FETCH object entered!\n");
STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);
FE_
}