X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FUpdates.h;h=07bd9de8863c65d15349e946b4086801cd85970c;hb=3a5b829ee532ba2c5641234737fde795d750f714;hp=04838e777cfeeb841b8a2745f6f27283ca51f2e9;hpb=ec48c5ab896b9334fa8d747c0a542e0679fe3a8f;p=ghc-hetmet.git diff --git a/ghc/includes/Updates.h b/ghc/includes/Updates.h index 04838e7..07bd9de 100644 --- a/ghc/includes/Updates.h +++ b/ghc/includes/Updates.h @@ -1,5 +1,7 @@ /* ----------------------------------------------------------------------------- - * $Id: Updates.h,v 1.6 1999/01/21 10:31:45 simonm Exp $ + * $Id: Updates.h,v 1.18 2000/05/15 14:38:11 simonmar Exp $ + * + * (c) The GHC Team, 1998-1999 * * Definitions related to updates. * @@ -24,29 +26,145 @@ * preferably don't use this macro inline in compiled code. */ -#define UPD_IND(updclosure, heapptr) \ - 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 + +/* 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)->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 + +#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) + + 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 ... a 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 == &BLACKHOLE_BQ_info || \ + info == &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); \ + } + +#elif defined(GRAN) + +extern void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node); +#define DO_AWAKEN_BQ(bq, node) STGCALL2(awakenBlockedQueue, bq, node); -#define AWAKEN_BQ(closure) \ - if (closure->header.info == &BLACKHOLE_BQ_info) { \ - StgTSO *bq = ((StgBlockingQueue *)closure)->blocking_queue;\ - if (bq != (StgTSO *)&END_TSO_QUEUE_closure) { \ - STGCALL1(awaken_blocked_queue, bq); \ - } \ +/* 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 == &BLACKHOLE_BQ_info || \ + get_itbl(closure)->type == RBH) { \ + StgBlockingQueueElement *bqe = ((StgBlockingQueue *)closure)->blocking_queue;\ + ASSERT(bqe!=END_BQ_QUEUE); \ + DO_AWAKEN_BQ(bqe, 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 == &BLACKHOLE_BQ_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 @@ -54,14 +172,14 @@ extern void awaken_blocked_queue(StgTSO *q); #define PUSH_STD_CCCS(frame) #endif -extern const StgPolyInfoTable Upd_frame_info; +extern DLL_IMPORT_DATA const StgPolyInfoTable 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 *)&upd_frame_info); \ __frame->link = Su; \ __frame->updatee = (StgClosure *)(target); \ PUSH_STD_CCCS(__frame); \ @@ -94,27 +212,36 @@ 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); \ - 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*)&IND_STATIC_info); \ } +#ifdef INTERPRETER +extern void newCAF_made_by_Hugs(StgCAF*); +#endif + /* ----------------------------------------------------------------------------- Update-related prototypes -------------------------------------------------------------------------- */ -extern STGFUN(Upd_frame_entry); +DLL_IMPORT_RTS extern STGFUN(upd_frame_entry); -extern const StgInfoTable PAP_info; -STGFUN(PAP_entry); +extern DLL_IMPORT_DATA const StgInfoTable PAP_info; +DLL_IMPORT_RTS STGFUN(PAP_entry); -EXTFUN(stg_update_PAP); +EXTFUN_RTS(stg_update_PAP); -extern const StgInfoTable AP_UPD_info; -STGFUN(AP_UPD_entry); +extern DLL_IMPORT_DATA const StgInfoTable AP_UPD_info; +DLL_IMPORT_RTS STGFUN(AP_UPD_entry); -extern const StgInfoTable raise_info; +extern DLL_IMPORT_DATA const StgInfoTable raise_info; #endif /* UPDATES_H */