1 /* ----------------------------------------------------------------------------
2 Time-stamp: <Tue Mar 06 2001 17:01:46 Stardate: [-30]6288.54 hwloidl>
4 Entry code for a FETCH_ME closure
6 This module defines routines for handling remote pointers (@FetchMe@s)
7 in GUM. It is threaded (@.hc@) because @FetchMe_entry@ will be
8 called during evaluation.
10 * --------------------------------------------------------------------------*/
12 #ifdef PAR /* all of it */
20 //@node Includes, Info tables
21 //@subsection Includes
29 #include "GranSimRts.h"
31 #include "ParallelRts.h"
34 #include "StgRun.h" /* for StgReturn and register saving */
36 /* --------------------------------------------------------------------------
39 A FETCH_ME closure represents data that currently resides on
40 another PE. We issue a fetch message, and wait for the data to be
43 A word on the ptr/nonptr fields in the macros: they are unused at the
44 moment; all closures defined here have constant size (ie. no payload
45 that varies from closure to closure). Therefore, all routines that
46 need to know the size of these closures have to do a sizeofW(StgFetchMe)
47 etc to get the closure size. See get_closure_info(), evacuate() and
48 checkClosure() (using the same fcts for determining the size of the
49 closures would be a good idea; at least it would be a nice step towards
50 making this code bug free).
51 ------------------------------------------------------------------------ */
53 //@node Info tables, Index, Includes
54 //@subsection Info tables
56 //@cindex FETCH_ME_info
57 INFO_TABLE(stg_FETCH_ME_info, stg_FETCH_ME_entry, 0,2, FETCH_ME,, EF_,"FETCH_ME","FETCH_ME");
58 //@cindex FETCH_ME_entry
59 STGFUN(stg_FETCH_ME_entry)
64 ASSERT(((StgFetchMe *)R1.p)->ga->payload.gc.gtid != mytid);
66 /* Turn the FETCH_ME into a FETCH_ME_BQ, and place the current thread
67 * on the blocking queue.
69 // ((StgFetchMeBlockingQueue *)R1.cl)->header.info = &FETCH_ME_BQ_info; // does the same as SET_INFO
70 SET_INFO((StgClosure *)R1.cl, &stg_FETCH_ME_BQ_info);
72 /* Remember GA as a global var (used in blockThread); NB: not thread safe! */
73 ASSERT(theGlobalFromGA.payload.gc.gtid == (GlobalTaskId)0);
74 theGlobalFromGA = *((StgFetchMe *)R1.p)->ga;
76 /* Put ourselves on the blocking queue for this black hole */
77 ASSERT(looks_like_ga(((StgFetchMe *)R1.p)->ga));
78 CurrentTSO->link = END_BQ_QUEUE;
79 ((StgFetchMeBlockingQueue *)R1.cl)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
81 /* jot down why and on what closure we are blocked */
82 CurrentTSO->why_blocked = BlockedOnGA;
83 CurrentTSO->block_info.closure = R1.cl;
84 /* closure is mutable since something has just been added to its BQ */
85 //recordMutable((StgMutClosure *)R1.cl);
87 /* sendFetch etc is now done in blockThread, which is called from the
94 /* ---------------------------------------------------------------------------
97 On the first entry of a FETCH_ME closure, we turn the closure into
98 a FETCH_ME_BQ, which behaves just like a BLACKHOLE_BQ. Any thread
99 entering the FETCH_ME_BQ will be placed in the blocking queue.
100 When the data arrives from the remote PE, all waiting threads are
101 woken up and the FETCH_ME_BQ is overwritten with the fetched data.
103 FETCH_ME_BQ_entry is almost identical to BLACKHOLE_BQ_entry -- HWL
104 ------------------------------------------------------------------------ */
106 INFO_TABLE(stg_FETCH_ME_BQ_info, stg_FETCH_ME_BQ_entry,0,2,FETCH_ME_BQ,,EF_,"FETCH_ME_BQ","FETCH_ME_BQ");
107 //@cindex FETCH_ME_BQ_info
108 STGFUN(stg_FETCH_ME_BQ_entry)
113 /* Put ourselves on the blocking queue for this node */
114 CurrentTSO->link = (StgTSO*)((StgBlockingQueue *)R1.p)->blocking_queue;
115 ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
117 /* jot down why and on what closure we are blocked */
118 CurrentTSO->why_blocked = BlockedOnGA_NoSend;
119 CurrentTSO->block_info.closure = R1.cl;
121 /* stg_gen_block is too heavyweight, use a specialised one */
126 /* ---------------------------------------------------------------------------
129 A BLOCKED_FETCH closure only ever exists in the blocking queue of a
130 globally visible closure i.e. one with a GA. A BLOCKED_FETCH closure
131 indicates that a TSO on another PE is waiting for the result of this
132 computation. Thus, when updating the closure, the result has to be sent
133 to that PE. The relevant routines handling that are awakenBlockedQueue
134 and blockFetch (for putting BLOCKED_FETCH closure into a BQ).
135 ------------------------------------------------------------------------ */
137 //@cindex BLOCKED_FETCH_info
138 INFO_TABLE(stg_BLOCKED_FETCH_info, stg_BLOCKED_FETCH_entry,0,2,BLOCKED_FETCH,,EF_,"BLOCKED_FETCH","BLOCKED_FETCH");
139 //@cindex BLOCKED_FETCH_entry
140 STGFUN(stg_BLOCKED_FETCH_entry)
143 /* see NON_ENTERABLE_ENTRY_CODE in StgMiscClosures.hc */
144 STGCALL2(fprintf,stderr,"BLOCKED_FETCH object entered!\n");
145 STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);
150 /* ---------------------------------------------------------------------------
153 A REMOTE_REF closure is generated whenever we wish to refer to a sticky
154 object on another PE.
155 ------------------------------------------------------------------------ */
157 //@cindex REMOTE_REF_info
158 INFO_TABLE(stg_REMOTE_REF_info, stg_REMOTE_REF_entry,0,2,REMOTE_REF,,EF_,"REMOTE_REF","REMOTE_REF");
159 //@cindex REMOTE_REF_entry
160 STGFUN(stg_REMOTE_REF_entry)
163 /* see NON_ENTERABLE_ENTRY_CODE in StgMiscClosures.hc */
164 STGCALL2(fprintf,stderr,"REMOTE REF object entered!\n");
165 STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);
171 //@node Index, , Info tables
175 //* BLOCKED_FETCH_entry:: @cindex\s-+BLOCKED_FETCH_entry
176 //* BLOCKED_FETCH_info:: @cindex\s-+BLOCKED_FETCH_info
177 //* FETCH_ME_BQ_info:: @cindex\s-+FETCH_ME_BQ_info
178 //* FETCH_ME_entry:: @cindex\s-+FETCH_ME_entry
179 //* FETCH_ME_info:: @cindex\s-+FETCH_ME_info