Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
181 lines (144 sloc) 6.33 KB
/* ----------------------------------------------------------------------------
Time-stamp: <Tue Mar 06 2001 17:01:46 Stardate: [-30]6288.54 hwloidl>
Entry code for a FETCH_ME closure
This module defines routines for handling remote pointers (@FetchMe@s)
in GUM. It is threaded (@.hc@) because @FetchMe_entry@ will be
called during evaluation.
* --------------------------------------------------------------------------*/
#ifdef PAR /* all of it */
//* Includes::
//* Info tables::
//* Index::
//@end menu
//@node Includes, Info tables
//@subsection Includes
#include "Stg.h"
#include "Rts.h"
#include "RtsFlags.h"
#include "RtsUtils.h"
#include "Storage.h"
#include "GranSim.h"
#include "GranSimRts.h"
#include "Parallel.h"
#include "ParallelRts.h"
#include "FetchMe.h"
#include "HLC.h"
#include "StgRun.h" /* for StgReturn and register saving */
/* --------------------------------------------------------------------------
FETCH_ME closures.
A FETCH_ME closure represents data that currently resides on
another PE. We issue a fetch message, and wait for the data to be
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).
------------------------------------------------------------------------ */
//@node Info tables, Index, Includes
//@subsection Info tables
//@cindex FETCH_ME_info
INFO_TABLE(stg_FETCH_ME_info, stg_FETCH_ME_entry, 0,2, FETCH_ME,, EF_,"FETCH_ME","FETCH_ME");
//@cindex FETCH_ME_entry
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.
// ((StgFetchMeBlockingQueue *)> = &FETCH_ME_BQ_info; // does the same as SET_INFO
SET_INFO((StgClosure *), &stg_FETCH_ME_BQ_info);
/* Remember GA as a global var (used in blockThread); NB: not thread safe! */
ASSERT(theGlobalFromGA.payload.gc.gtid == (GlobalTaskId)0);
theGlobalFromGA = *((StgFetchMe *)R1.p)->ga;
/* Put ourselves on the blocking queue for this black hole */
ASSERT(looks_like_ga(((StgFetchMe *)R1.p)->ga));
CurrentTSO->link = END_BQ_QUEUE;
((StgFetchMeBlockingQueue *)>blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
/* jot down why and on what closure we are blocked */
CurrentTSO->why_blocked = BlockedOnGA;
CurrentTSO->block_info.closure =;
/* closure is mutable since something has just been added to its BQ */
//recordMutable((StgMutClosure *);
/* sendFetch etc is now done in blockThread, which is called from the
scheduler -- HWL */
/* ---------------------------------------------------------------------------
On the first entry of a FETCH_ME closure, we turn the closure into
a FETCH_ME_BQ, which behaves just like a BLACKHOLE_BQ. Any thread
entering the FETCH_ME_BQ will be placed in the blocking queue.
When the data arrives from the remote PE, all waiting threads are
woken up and the FETCH_ME_BQ is overwritten with the fetched data.
FETCH_ME_BQ_entry is almost identical to BLACKHOLE_BQ_entry -- HWL
------------------------------------------------------------------------ */
//@cindex FETCH_ME_BQ_info
/* Put ourselves on the blocking queue for this node */
CurrentTSO->link = (StgTSO*)((StgBlockingQueue *)R1.p)->blocking_queue;
((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
/* jot down why and on what closure we are blocked */
CurrentTSO->why_blocked = BlockedOnGA_NoSend;
CurrentTSO->block_info.closure =;
/* stg_gen_block is too heavyweight, use a specialised one */
/* ---------------------------------------------------------------------------
A BLOCKED_FETCH closure only ever exists in the blocking queue of a
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 awakenBlockedQueue
and blockFetch (for putting BLOCKED_FETCH closure into a BQ).
------------------------------------------------------------------------ */
//@cindex BLOCKED_FETCH_info
//@cindex BLOCKED_FETCH_entry
/* see NON_ENTERABLE_ENTRY_CODE in StgMiscClosures.hc */
STGCALL2(fprintf,stderr,"BLOCKED_FETCH object entered!\n");
STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);
/* ---------------------------------------------------------------------------
A REMOTE_REF closure is generated whenever we wish to refer to a sticky
object on another PE.
------------------------------------------------------------------------ */
//@cindex REMOTE_REF_info
//@cindex REMOTE_REF_entry
/* see NON_ENTERABLE_ENTRY_CODE in StgMiscClosures.hc */
STGCALL2(fprintf,stderr,"REMOTE REF object entered!\n");
STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);
#endif /* PAR */
//@node Index, , Info tables
//@subsection Index
//* BLOCKED_FETCH_entry:: @cindex\s-+BLOCKED_FETCH_entry
//* BLOCKED_FETCH_info:: @cindex\s-+BLOCKED_FETCH_info
//* FETCH_ME_BQ_info:: @cindex\s-+FETCH_ME_BQ_info
//* FETCH_ME_entry:: @cindex\s-+FETCH_ME_entry
//* FETCH_ME_info:: @cindex\s-+FETCH_ME_info
//@end index
Something went wrong with that request. Please try again.