X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FUpdates.h;h=87b7bd62671786c5eb3f3775597d05ea60c3e233;hb=9c383315203f0ad7cfd65272d04d921c0cef3cec;hp=3a599c220b8c563c2a107897204c67803f031297;hpb=4391e44f910ce579f269986faef9e5db8907a6c0;p=ghc-hetmet.git diff --git a/ghc/includes/Updates.h b/ghc/includes/Updates.h index 3a599c2..87b7bd6 100644 --- a/ghc/includes/Updates.h +++ b/ghc/includes/Updates.h @@ -1,5 +1,7 @@ /* ----------------------------------------------------------------------------- - * $Id: Updates.h,v 1.3 1999/01/13 17:25:55 simonm Exp $ + * $Id: Updates.h,v 1.27 2001/12/10 18:07:09 sof Exp $ + * + * (c) The GHC Team, 1998-1999 * * Definitions related to updates. * @@ -24,57 +26,173 @@ * preferably don't use this macro inline in compiled code. */ -#define UPD_IND(updclosure, heapptr) \ - TICK_UPDATED_SET_UPDATED(updclosure); \ - AWAKEN_BQ(updclosure); \ - updateWithIndirection((StgClosure *)updclosure, \ - (StgClosure *)heapptr); +#ifdef TICKY_TICKY +# define UPD_IND(updclosure, heapptr) UPD_PERM_IND(updclosure,heapptr) +#else +# define UPD_IND(updclosure, heapptr) UPD_REAL_IND(updclosure,heapptr) +#endif -/* ----------------------------------------------------------------------------- - Update a closure inplace with an infotable that expects 1 (closure) - argument. - Also may wake up BQs. - -------------------------------------------------------------------------- */ +/* 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) \ + { \ + const StgInfoTable *info; \ + if (Bdescr((P_)updclosure)->u.back != (bdescr *)BaseReg) { \ + info = LOCK_CLOSURE(updclosure); \ + } else { \ + info = updclosure->header.info; \ + } \ + AWAKEN_BQ(info,updclosure); \ + updateWithIndirection(info, \ + (StgClosure *)updclosure, \ + (StgClosure *)heapptr); \ + } +#else +#define UPD_REAL_IND(updclosure, heapptr) \ + { \ + const StgInfoTable *info; \ + info = ((StgClosure *)updclosure)->header.info; \ + AWAKEN_BQ(info,updclosure); \ + updateWithIndirection(info, \ + (StgClosure *)updclosure, \ + (StgClosure *)heapptr); \ + } +#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); \ + } -#define UPD_INPLACE1(updclosure,info,c0) \ - TICK_UPDATED_SET_UPDATED(updclosure); \ - AWAKEN_BQ(updclosure); \ - SET_INFO(updclosure,info); \ - payloadCPtr(updclosure,0) = (c0) +#if defined(PROFILING) || defined(TICKY_TICKY) +#define UPD_PERM_IND(updclosure, heapptr) \ + { \ + const StgInfoTable *info; \ + info = ((StgClosure *)updclosure)->header.info; \ + AWAKEN_BQ(info,updclosure); \ + updateWithPermIndirection(info, \ + (StgClosure *)updclosure, \ + (StgClosure *)heapptr); \ + } +#endif + +#ifdef SMP +#define UPD_IND_NOLOCK(updclosure, heapptr) \ + { \ + const StgInfoTable *info; \ + info = updclosure->header.info; \ + AWAKEN_BQ(info,updclosure); \ + updateWithIndirection(info, \ + (StgClosure *)updclosure, \ + (StgClosure *)heapptr); \ + } +#else +#define UPD_IND_NOLOCK(updclosure,heapptr) UPD_IND(updclosure,heapptr) +#endif /* ----------------------------------------------------------------------------- Awaken any threads waiting on this computation -------------------------------------------------------------------------- */ -extern void awaken_blocked_queue(StgTSO *q); +#if defined(PAR) + +/* + 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 + FETCH_ME_BQ ... a global indirection (FETCH_ME) may be entered by a + local TSO, turning it into a FETCH_ME_BQ; it will be + reawakened via calling processResume + RBH ... a revertible black hole may be entered by another + local TSO, putting it onto its blocking queue; since + RBHs only exist while the corresponding closure is in + transit, they will be reawakened via calling + convertToFetchMe (upon processing an ACK message) -#define AWAKEN_BQ(closure) \ - if (closure->header.info == &BLACKHOLE_info) { \ - StgTSO *bq = ((StgBlackHole *)closure)->blocking_queue; \ - if (bq != (StgTSO *)&END_TSO_QUEUE_closure) { \ - STGCALL1(awaken_blocked_queue, bq); \ - } \ + In a parallel setup a blocking queue may contain 3 types of closures: + 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 ... 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 + blocking queue for an RBH closure; it only exists in + this kind of blocking queue and must be at the end + of the queue +*/ +extern void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node); +#define DO_AWAKEN_BQ(bqe, node) STGCALL2(awakenBlockedQueue, bqe, node); + +#define AWAKEN_BQ(info,closure) \ + if (info == &stg_BLACKHOLE_BQ_info || \ + info == &stg_FETCH_ME_BQ_info || \ + get_itbl(closure)->type == RBH) { \ + DO_AWAKEN_BQ(((StgBlockingQueue *)closure)->blocking_queue, closure); \ } +#elif defined(GRAN) -/* ----------------------------------------------------------------------------- +extern void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node); +#define DO_AWAKEN_BQ(bq, node) STGCALL2(awakenBlockedQueue, bq, node); + +/* In GranSim we don't have FETCH_ME or FETCH_ME_BQ closures, so they are + not checked. The rest of the code is the same as for GUM. +*/ +#define AWAKEN_BQ(info,closure) \ + if (info == &stg_BLACKHOLE_BQ_info || \ + get_itbl(closure)->type == RBH) { \ + DO_AWAKEN_BQ(((StgBlockingQueue *)closure)->blocking_queue, closure); \ + } + + +#else /* !GRAN && !PAR */ + +extern void awakenBlockedQueue(StgTSO *q); +#define DO_AWAKEN_BQ(closure) \ + STGCALL1(awakenBlockedQueue, \ + ((StgBlockingQueue *)closure)->blocking_queue); + +#define AWAKEN_BQ(info,closure) \ + 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); \ + } + +#endif /* GRAN || PAR */ + +/* ------------------------------------------------------------------------- Push an update frame on the stack. - -------------------------------------------------------------------------- */ + ------------------------------------------------------------------------- */ #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 const StgPolyInfoTable Upd_frame_info; +extern DLL_IMPORT_RTS const StgPolyInfoTable stg_upd_frame_info; #define PUSH_UPD_FRAME(target, Sp_offset) \ { \ StgUpdateFrame *__frame; \ - TICK_UPDF_PUSHED(); \ - __frame = stgCast(StgUpdateFrame*,Sp + (Sp_offset)) - 1; \ - SET_INFO(__frame,stgCast(StgInfoTable*,&Upd_frame_info)); \ + TICK_UPDF_PUSHED(target, GET_INFO((StgClosure*)target)); \ + __frame = (StgUpdateFrame *)(Sp + (Sp_offset)) - 1; \ + SET_INFO(__frame, (StgInfoTable *)&stg_upd_frame_info); \ __frame->link = Su; \ __frame->updatee = (StgClosure *)(target); \ PUSH_STD_CCCS(__frame); \ @@ -107,29 +225,32 @@ extern const StgPolyInfoTable Upd_frame_info; extern void newCAF(StgClosure*); -#define UPD_CAF(cafptr, bhptr) \ - { \ - SET_INFO((StgInd *)cafptr,&IND_STATIC_info); \ - ((StgInd *)cafptr)->indirectee = (StgClosure *)(bhptr); \ - ((StgBlackHole *)(bhptr))->blocking_queue = \ - (StgTSO *)&END_TSO_QUEUE_closure; \ - STGCALL1(newCAF,(StgClosure *)cafptr); \ +/* 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); \ + STGCALL1(newCAF,(StgClosure *)cafptr); \ + ((StgInd *)cafptr)->indirectee = (StgClosure *)(bhptr); \ + SET_INFO((StgInd *)cafptr,(const StgInfoTable*)&stg_IND_STATIC_info);\ } /* ----------------------------------------------------------------------------- Update-related prototypes -------------------------------------------------------------------------- */ -extern STGFUN(Upd_frame_entry); +EXTFUN_RTS(__stg_update_PAP); -extern const StgInfoTable PAP_info; -STGFUN(PAP_entry); +DLL_IMPORT_RTS extern STGFUN(stg_upd_frame_entry); -EXTFUN(stg_update_PAP); +extern DLL_IMPORT_RTS const StgInfoTable stg_PAP_info; +DLL_IMPORT_RTS STGFUN(stg_PAP_entry); -extern const StgInfoTable AP_UPD_info; -STGFUN(AP_UPD_entry); +extern DLL_IMPORT_RTS const StgInfoTable stg_AP_UPD_info; +DLL_IMPORT_RTS STGFUN(stg_AP_UPD_entry); -extern const StgInfoTable raise_info; +extern DLL_IMPORT_RTS const StgInfoTable stg_raise_info; #endif /* UPDATES_H */