1 /* -----------------------------------------------------------------------------
2 * $Id: Updates.h,v 1.9 1999/03/18 17:57:20 simonm Exp $
4 * (c) The GHC Team, 1998-1999
6 * Definitions related to updates.
8 * ---------------------------------------------------------------------------*/
13 /* -----------------------------------------------------------------------------
14 Update a closure with an indirection. This may also involve waking
15 up a queue of blocked threads waiting on the result of this
17 -------------------------------------------------------------------------- */
19 /* ToDo: overwrite slop words with something safe in case sanity checking
21 * (I think the fancy version of the GC is supposed to do this too.)
24 /* This expands to a fair chunk of code, what with waking up threads
25 * and checking whether we're updating something in a old generation.
26 * preferably don't use this macro inline in compiled code.
29 #define UPD_IND(updclosure, heapptr) \
30 AWAKEN_BQ(updclosure); \
31 updateWithIndirection((StgClosure *)updclosure, \
32 (StgClosure *)heapptr);
35 #define UPD_PERM_IND(updclosure, heapptr) \
36 AWAKEN_BQ(updclosure); \
37 updateWithPermIndirection((StgClosure *)updclosure, \
38 (StgClosure *)heapptr);
41 /* -----------------------------------------------------------------------------
42 Awaken any threads waiting on this computation
43 -------------------------------------------------------------------------- */
45 extern void awaken_blocked_queue(StgTSO *q);
47 #define AWAKEN_BQ(closure) \
48 if (closure->header.info == &BLACKHOLE_BQ_info) { \
49 StgTSO *bq = ((StgBlockingQueue *)closure)->blocking_queue;\
50 if (bq != (StgTSO *)&END_TSO_QUEUE_closure) { \
51 STGCALL1(awaken_blocked_queue, bq); \
56 /* -----------------------------------------------------------------------------
57 Push an update frame on the stack.
58 -------------------------------------------------------------------------- */
60 #if defined(PROFILING)
61 #define PUSH_STD_CCCS(frame) frame->header.prof.ccs = CCCS
63 #define PUSH_STD_CCCS(frame)
66 extern DLL_IMPORT_DATA const StgPolyInfoTable Upd_frame_info;
68 #define PUSH_UPD_FRAME(target, Sp_offset) \
70 StgUpdateFrame *__frame; \
72 __frame = stgCast(StgUpdateFrame*,Sp + (Sp_offset)) - 1; \
73 SET_INFO(__frame,stgCast(StgInfoTable*,&Upd_frame_info)); \
75 __frame->updatee = (StgClosure *)(target); \
76 PUSH_STD_CCCS(__frame); \
80 /* -----------------------------------------------------------------------------
83 When a CAF is first entered, it creates a black hole in the heap,
84 and updates itself with an indirection to this new black hole.
86 We update the CAF with an indirection to a newly-allocated black
87 hole in the heap. We also set the blocking queue on the newly
88 allocated black hole to be empty.
90 Why do we make a black hole in the heap when we enter a CAF?
92 - for a generational garbage collector, which needs a fast
93 test for whether an updatee is in an old generation or not
95 - for the parallel system, which can implement updates more
96 easily if the updatee is always in the heap. (allegedly).
98 When debugging, we maintain a separate CAF list so we can tell when
99 a CAF has been garbage collected.
100 -------------------------------------------------------------------------- */
102 /* ToDo: only call newCAF when debugging. */
104 extern void newCAF(StgClosure*);
106 #define UPD_CAF(cafptr, bhptr) \
108 SET_INFO((StgInd *)cafptr,(const StgInfoTable*)&IND_STATIC_info); \
109 ((StgInd *)cafptr)->indirectee = (StgClosure *)(bhptr); \
110 STGCALL1(newCAF,(StgClosure *)cafptr); \
113 /* -----------------------------------------------------------------------------
114 Update-related prototypes
115 -------------------------------------------------------------------------- */
117 DLL_IMPORT_RTS extern STGFUN(Upd_frame_entry);
119 extern DLL_IMPORT_DATA const StgInfoTable PAP_info;
120 DLL_IMPORT_RTS STGFUN(PAP_entry);
122 EXTFUN_RTS(stg_update_PAP);
124 extern DLL_IMPORT_DATA const StgInfoTable AP_UPD_info;
125 DLL_IMPORT_RTS STGFUN(AP_UPD_entry);
127 extern DLL_IMPORT_DATA const StgInfoTable raise_info;
129 #endif /* UPDATES_H */