1 /* -----------------------------------------------------------------------------
2 * $Id: Updates.h,v 1.2 1998/12/02 13:21:47 simonm Exp $
4 * Definitions related to updates.
6 * ---------------------------------------------------------------------------*/
12 ticky-ticky wants to use permanent indirections when it's doing
17 # define Ind_info_TO_USE &IND_info
19 # define Ind_info_TO_USE ((AllFlags.doUpdEntryCounts) ? &IND_PERM_info : &IND_info
23 /* -----------------------------------------------------------------------------
24 Update a closure with an indirection. This may also involve waking
25 up a queue of blocked threads waiting on the result of this
27 -------------------------------------------------------------------------- */
29 /* ToDo: overwrite slop words with something safe in case sanity checking
31 * (I think the fancy version of the GC is supposed to do this too.)
34 #define UPD_IND(updclosure, heapptr) \
35 TICK_UPDATED_SET_UPDATED(updclosure); \
36 AWAKEN_BQ(updclosure); \
37 SET_INFO((StgInd*)updclosure,Ind_info_TO_USE); \
38 ((StgInd *)updclosure)->indirectee = (StgClosure *)(heapptr)
40 /* -----------------------------------------------------------------------------
41 Update a closure inplace with an infotable that expects 1 (closure)
44 -------------------------------------------------------------------------- */
46 #define UPD_INPLACE1(updclosure,info,c0) \
47 TICK_UPDATED_SET_UPDATED(updclosure); \
48 AWAKEN_BQ(updclosure); \
49 SET_INFO(updclosure,info); \
50 payloadCPtr(updclosure,0) = (c0)
52 /* -----------------------------------------------------------------------------
53 Awaken any threads waiting on this computation
54 -------------------------------------------------------------------------- */
56 extern void awaken_blocked_queue(StgTSO *q);
58 #define AWAKEN_BQ(closure) \
59 if (closure->header.info == &BLACKHOLE_info) { \
60 StgTSO *bq = ((StgBlackHole *)closure)->blocking_queue; \
61 if (bq != (StgTSO *)&END_TSO_QUEUE_closure) { \
62 STGCALL1(awaken_blocked_queue, bq); \
67 /* -----------------------------------------------------------------------------
68 Push an update frame on the stack.
69 -------------------------------------------------------------------------- */
71 #if defined(PROFILING)
72 #define PUSH_STD_CCCS(frame) frame->header.prof.ccs = CCCS
74 #define PUSH_STD_CCCS(frame)
77 extern const StgPolyInfoTable Upd_frame_info;
79 #define PUSH_UPD_FRAME(target, Sp_offset) \
81 StgUpdateFrame *__frame; \
83 __frame = stgCast(StgUpdateFrame*,Sp + (Sp_offset)) - 1; \
84 SET_INFO(__frame,stgCast(StgInfoTable*,&Upd_frame_info)); \
86 __frame->updatee = (StgClosure *)(target); \
87 PUSH_STD_CCCS(__frame); \
91 /* -----------------------------------------------------------------------------
94 When a CAF is first entered, it creates a black hole in the heap,
95 and updates itself with an indirection to this new black hole.
97 We update the CAF with an indirection to a newly-allocated black
98 hole in the heap. We also set the blocking queue on the newly
99 allocated black hole to be empty.
101 Why do we make a black hole in the heap when we enter a CAF?
103 - for a generational garbage collector, which needs a fast
104 test for whether an updatee is in an old generation or not
106 - for the parallel system, which can implement updates more
107 easily if the updatee is always in the heap. (allegedly).
108 -------------------------------------------------------------------------- */
113 /* ToDo: only call newCAF when debugging. */
115 extern void newCAF(StgClosure*);
117 #define UPD_CAF(cafptr, bhptr) \
119 SET_INFO((StgInd *)cafptr,&IND_STATIC_info); \
120 ((StgInd *)cafptr)->indirectee = (StgClosure *)(bhptr); \
121 ((StgBlackHole *)(bhptr))->blocking_queue = \
122 (StgTSO *)&END_TSO_QUEUE_closure; \
123 STGCALL1(newCAF,(StgClosure *)cafptr); \
126 /* -----------------------------------------------------------------------------
127 Update-related prototypes
128 -------------------------------------------------------------------------- */
130 extern STGFUN(Upd_frame_entry);
132 extern const StgInfoTable PAP_info;
135 EXTFUN(stg_update_PAP);
137 extern const StgInfoTable AP_UPD_info;
138 STGFUN(AP_UPD_entry);
140 extern const StgInfoTable raise_info;
142 #endif /* UPDATES_H */