/* -----------------------------------------------------------------------------
- * $Id: Updates.h,v 1.16 2000/01/13 14:34:01 hwloidl Exp $
+ * $Id: Updates.h,v 1.34 2003/11/12 17:27:06 sof Exp $
*
* (c) The GHC Team, 1998-1999
*
*/
#ifdef TICKY_TICKY
-# define UPD_IND(updclosure, heapptr) UPD_PERM_IND(updclosure,heapptr)
+# define UPD_IND(updclosure, heapptr) \
+ UPD_PERM_IND(updclosure,heapptr)
+# define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \
+ UPD_PERM_IND(updclosure,heapptr); and_then
#else
-# define UPD_IND(updclosure, heapptr) UPD_REAL_IND(updclosure,heapptr)
+# define SEMI ;
+# define UPD_IND(updclosure, heapptr) \
+ UPD_REAL_IND(updclosure,&stg_IND_info,heapptr,SEMI)
+# define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \
+ UPD_REAL_IND(updclosure,ind_info,heapptr,and_then)
#endif
/* UPD_IND actually does a PERM_IND if TICKY_TICKY is on;
if you *really* need an IND use UPD_REAL_IND
*/
#ifdef SMP
-#define UPD_REAL_IND(updclosure, heapptr) \
+#define UPD_REAL_IND(updclosure, ind_info, heapptr, and_then) \
{ \
const StgInfoTable *info; \
- if (Bdescr((P_)updclosure)->back != (bdescr *)BaseReg) { \
+ if (Bdescr((P_)updclosure)->u.back != (bdescr *)BaseReg) { \
info = LOCK_CLOSURE(updclosure); \
} else { \
info = updclosure->header.info; \
} \
AWAKEN_BQ(info,updclosure); \
- updateWithIndirection(info, \
+ updateWithIndirection(info, ind_info, \
(StgClosure *)updclosure, \
- (StgClosure *)heapptr); \
+ (StgClosure *)heapptr, \
+ and_then); \
}
#else
-#define UPD_REAL_IND(updclosure, heapptr) \
+#define UPD_REAL_IND(updclosure, ind_info, heapptr, and_then) \
{ \
const StgInfoTable *info; \
info = ((StgClosure *)updclosure)->header.info; \
AWAKEN_BQ(info,updclosure); \
- updateWithIndirection(info, \
+ updateWithIndirection(((StgClosure *)updclosure)->header.info, ind_info, \
(StgClosure *)updclosure, \
- (StgClosure *)heapptr); \
+ (StgClosure *)heapptr, \
+ and_then); \
}
#endif
+#define UPD_STATIC_IND(updclosure, heapptr) \
+ { \
+ const StgInfoTable *info; \
+ info = ((StgClosure *)updclosure)->header.info; \
+ AWAKEN_STATIC_BQ(info,updclosure); \
+ updateWithStaticIndirection(info, \
+ (StgClosure *)updclosure, \
+ (StgClosure *)heapptr); \
+ }
+
#if defined(PROFILING) || defined(TICKY_TICKY)
#define UPD_PERM_IND(updclosure, heapptr) \
{ \
const StgInfoTable *info; \
info = updclosure->header.info; \
AWAKEN_BQ(info,updclosure); \
- updateWithIndirection(info, \
+ updateWithIndirection(info,&stg_IND_info, \
(StgClosure *)updclosure, \
- (StgClosure *)heapptr); \
+ (StgClosure *)heapptr,); \
+ }
+#elif defined(RTS_SUPPORTS_THREADS)
+
+# ifdef TICKY_TICKY
+# define UPD_IND_NOLOCK(updclosure, heapptr) \
+ { \
+ const StgInfoTable *info; \
+ info = ((StgClosure *)updclosure)->header.info; \
+ AWAKEN_BQ_NOLOCK(info,updclosure); \
+ updateWithPermIndirection(info, \
+ (StgClosure *)updclosure, \
+ (StgClosure *)heapptr); \
+ }
+# else
+# define UPD_IND_NOLOCK(updclosure, heapptr) \
+ { \
+ const StgInfoTable *info; \
+ info = ((StgClosure *)updclosure)->header.info; \
+ AWAKEN_BQ_NOLOCK(info,updclosure); \
+ updateWithIndirection(info,&stg_IND_info, \
+ (StgClosure *)updclosure, \
+ (StgClosure *)heapptr,); \
}
+# endif
+
#else
#define UPD_IND_NOLOCK(updclosure,heapptr) UPD_IND(updclosure,heapptr)
#endif
#if defined(PAR)
/*
- In a parallel setup several types of closures, might have a blocking queue:
+ In a parallel setup several types of closures might have a blocking queue:
BLACKHOLE_BQ ... same as in the default concurrent setup; it will be
reawakened via calling UPD_IND on that closure after
having finished the computation of the graph
TSO ... as in the default concurrent setup
BLOCKED_FETCH ... indicating that a TSO on another PE is waiting for
the result of the current computation
- CONSTR ... a RBHSave closure (which contains data ripped out of
+ CONSTR ... an RBHSave closure (which contains data ripped out of
the closure to make room for a blocking queue; since
it only contains data we use the exisiting type of
a CONSTR closure); this closure is the end of a
#define DO_AWAKEN_BQ(bqe, node) STGCALL2(awakenBlockedQueue, bqe, node);
#define AWAKEN_BQ(info,closure) \
- if (info == &BLACKHOLE_BQ_info || \
- info == &FETCH_ME_BQ_info || \
+ if (info == &stg_BLACKHOLE_BQ_info || \
+ info == &stg_FETCH_ME_BQ_info || \
get_itbl(closure)->type == RBH) { \
- StgBlockingQueueElement *bqe = ((StgBlockingQueue *)closure)->blocking_queue;\
- ASSERT(bqe!=END_BQ_QUEUE); \
- DO_AWAKEN_BQ(bqe, closure); \
+ DO_AWAKEN_BQ(((StgBlockingQueue *)closure)->blocking_queue, closure); \
}
#elif defined(GRAN)
not checked. The rest of the code is the same as for GUM.
*/
#define AWAKEN_BQ(info,closure) \
- if (info == &BLACKHOLE_BQ_info || \
+ if (info == &stg_BLACKHOLE_BQ_info || \
get_itbl(closure)->type == RBH) { \
- StgBlockingQueueElement *bqe = ((StgBlockingQueue *)closure)->blocking_queue;\
- ASSERT(bqe!=END_BQ_QUEUE); \
- DO_AWAKEN_BQ(bqe, closure); \
+ DO_AWAKEN_BQ(((StgBlockingQueue *)closure)->blocking_queue, closure); \
}
((StgBlockingQueue *)closure)->blocking_queue);
#define AWAKEN_BQ(info,closure) \
- if (info == &BLACKHOLE_BQ_info) { \
+ if (info == &stg_BLACKHOLE_BQ_info) { \
+ DO_AWAKEN_BQ(closure); \
+ }
+
+#define AWAKEN_STATIC_BQ(info,closure) \
+ if (info == &stg_BLACKHOLE_BQ_STATIC_info) { \
DO_AWAKEN_BQ(closure); \
}
+#ifdef RTS_SUPPORTS_THREADS
+extern void awakenBlockedQueueNoLock(StgTSO *q);
+#define DO_AWAKEN_BQ_NOLOCK(closure) \
+ STGCALL1(awakenBlockedQueueNoLock, \
+ ((StgBlockingQueue *)closure)->blocking_queue);
+
+#define AWAKEN_BQ_NOLOCK(info,closure) \
+ if (info == &stg_BLACKHOLE_BQ_info) { \
+ DO_AWAKEN_BQ_NOLOCK(closure); \
+ }
+#endif
#endif /* GRAN || PAR */
/* -------------------------------------------------------------------------
------------------------------------------------------------------------- */
#if defined(PROFILING)
-#define PUSH_STD_CCCS(frame) frame->header.prof.ccs = CCCS
+// frame->header.prof.hp.rs = NULL (or frame-header.prof.hp.ldvw = 0) is unnecessary
+// because it is not used anyhow.
+#define PUSH_STD_CCCS(frame) (frame->header.prof.ccs = CCCS)
#else
#define PUSH_STD_CCCS(frame)
#endif
-extern DLL_IMPORT_DATA const StgPolyInfoTable Upd_frame_info;
+extern DLL_IMPORT_RTS const StgPolyInfoTable stg_upd_frame_info;
+extern DLL_IMPORT_RTS const StgPolyInfoTable stg_noupd_frame_info;
#define PUSH_UPD_FRAME(target, Sp_offset) \
{ \
StgUpdateFrame *__frame; \
TICK_UPDF_PUSHED(target, GET_INFO((StgClosure*)target)); \
__frame = (StgUpdateFrame *)(Sp + (Sp_offset)) - 1; \
- SET_INFO(__frame, (StgInfoTable *)&Upd_frame_info); \
- __frame->link = Su; \
+ SET_INFO(__frame, (StgInfoTable *)&stg_upd_frame_info); \
__frame->updatee = (StgClosure *)(target); \
PUSH_STD_CCCS(__frame); \
- Su = __frame; \
}
/* -----------------------------------------------------------------------------
extern void newCAF(StgClosure*);
+/* newCAF must be called before the itbl ptr is overwritten, since
+ newCAF records the old itbl ptr in order to do CAF reverting
+ (which Hugs needs to do in order that combined mode works right.)
+*/
#define UPD_CAF(cafptr, bhptr) \
{ \
LOCK_CLOSURE(cafptr); \
- ((StgInd *)cafptr)->indirectee = (StgClosure *)(bhptr); \
- SET_INFO((StgInd *)cafptr,(const StgInfoTable*)&IND_STATIC_info); \
STGCALL1(newCAF,(StgClosure *)cafptr); \
+ ((StgInd *)cafptr)->indirectee = (StgClosure *)(bhptr); \
+ SET_INFO((StgInd *)cafptr,(const StgInfoTable*)&stg_IND_STATIC_info);\
}
/* -----------------------------------------------------------------------------
Update-related prototypes
-------------------------------------------------------------------------- */
-DLL_IMPORT_RTS extern STGFUN(Upd_frame_entry);
-
-extern DLL_IMPORT_DATA const StgInfoTable PAP_info;
-DLL_IMPORT_RTS STGFUN(PAP_entry);
-
-EXTFUN_RTS(stg_update_PAP);
-
-extern DLL_IMPORT_DATA const StgInfoTable AP_UPD_info;
-DLL_IMPORT_RTS STGFUN(AP_UPD_entry);
-
-extern DLL_IMPORT_DATA const StgInfoTable raise_info;
-
#endif /* UPDATES_H */