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