1 /* -----------------------------------------------------------------------------
2 * $Id: Updates.h,v 1.3 1999/01/13 17:25:55 simonm Exp $
4 * Definitions related to updates.
6 * ---------------------------------------------------------------------------*/
11 /* -----------------------------------------------------------------------------
12 Update a closure with an indirection. This may also involve waking
13 up a queue of blocked threads waiting on the result of this
15 -------------------------------------------------------------------------- */
17 /* ToDo: overwrite slop words with something safe in case sanity checking
19 * (I think the fancy version of the GC is supposed to do this too.)
22 /* This expands to a fair chunk of code, what with waking up threads
23 * and checking whether we're updating something in a old generation.
24 * preferably don't use this macro inline in compiled code.
27 #define UPD_IND(updclosure, heapptr) \
28 TICK_UPDATED_SET_UPDATED(updclosure); \
29 AWAKEN_BQ(updclosure); \
30 updateWithIndirection((StgClosure *)updclosure, \
31 (StgClosure *)heapptr);
33 /* -----------------------------------------------------------------------------
34 Update a closure inplace with an infotable that expects 1 (closure)
37 -------------------------------------------------------------------------- */
39 #define UPD_INPLACE1(updclosure,info,c0) \
40 TICK_UPDATED_SET_UPDATED(updclosure); \
41 AWAKEN_BQ(updclosure); \
42 SET_INFO(updclosure,info); \
43 payloadCPtr(updclosure,0) = (c0)
45 /* -----------------------------------------------------------------------------
46 Awaken any threads waiting on this computation
47 -------------------------------------------------------------------------- */
49 extern void awaken_blocked_queue(StgTSO *q);
51 #define AWAKEN_BQ(closure) \
52 if (closure->header.info == &BLACKHOLE_info) { \
53 StgTSO *bq = ((StgBlackHole *)closure)->blocking_queue; \
54 if (bq != (StgTSO *)&END_TSO_QUEUE_closure) { \
55 STGCALL1(awaken_blocked_queue, bq); \
60 /* -----------------------------------------------------------------------------
61 Push an update frame on the stack.
62 -------------------------------------------------------------------------- */
64 #if defined(PROFILING)
65 #define PUSH_STD_CCCS(frame) frame->header.prof.ccs = CCCS
67 #define PUSH_STD_CCCS(frame)
70 extern const StgPolyInfoTable Upd_frame_info;
72 #define PUSH_UPD_FRAME(target, Sp_offset) \
74 StgUpdateFrame *__frame; \
76 __frame = stgCast(StgUpdateFrame*,Sp + (Sp_offset)) - 1; \
77 SET_INFO(__frame,stgCast(StgInfoTable*,&Upd_frame_info)); \
79 __frame->updatee = (StgClosure *)(target); \
80 PUSH_STD_CCCS(__frame); \
84 /* -----------------------------------------------------------------------------
87 When a CAF is first entered, it creates a black hole in the heap,
88 and updates itself with an indirection to this new black hole.
90 We update the CAF with an indirection to a newly-allocated black
91 hole in the heap. We also set the blocking queue on the newly
92 allocated black hole to be empty.
94 Why do we make a black hole in the heap when we enter a CAF?
96 - for a generational garbage collector, which needs a fast
97 test for whether an updatee is in an old generation or not
99 - for the parallel system, which can implement updates more
100 easily if the updatee is always in the heap. (allegedly).
102 When debugging, we maintain a separate CAF list so we can tell when
103 a CAF has been garbage collected.
104 -------------------------------------------------------------------------- */
106 /* ToDo: only call newCAF when debugging. */
108 extern void newCAF(StgClosure*);
110 #define UPD_CAF(cafptr, bhptr) \
112 SET_INFO((StgInd *)cafptr,&IND_STATIC_info); \
113 ((StgInd *)cafptr)->indirectee = (StgClosure *)(bhptr); \
114 ((StgBlackHole *)(bhptr))->blocking_queue = \
115 (StgTSO *)&END_TSO_QUEUE_closure; \
116 STGCALL1(newCAF,(StgClosure *)cafptr); \
119 /* -----------------------------------------------------------------------------
120 Update-related prototypes
121 -------------------------------------------------------------------------- */
123 extern STGFUN(Upd_frame_entry);
125 extern const StgInfoTable PAP_info;
128 EXTFUN(stg_update_PAP);
130 extern const StgInfoTable AP_UPD_info;
131 STGFUN(AP_UPD_entry);
133 extern const StgInfoTable raise_info;
135 #endif /* UPDATES_H */