X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FUpdates.h;h=0467c07f80e16fb420137d583ab5628016cd80f8;hb=425008f93f115f9d5c92543e32838a47a7a7790f;hp=e142cd0e9ec1c52e1728160352aae73f7de83755;hpb=c6ab4bfa09886be3bfff4aa747af2f1c8e348a1f;p=ghc-hetmet.git diff --git a/ghc/includes/Updates.h b/ghc/includes/Updates.h index e142cd0..0467c07 100644 --- a/ghc/includes/Updates.h +++ b/ghc/includes/Updates.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Updates.h,v 1.12 1999/08/25 16:11:44 simonmar Exp $ + * $Id: Updates.h,v 1.32 2003/07/18 14:39:05 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -27,63 +27,225 @@ */ #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 UPD_IND(updclosure, heapptr) \ + UPD_REAL_IND(updclosure,&stg_IND_info,heapptr,) +# 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 */ -#define UPD_REAL_IND(updclosure, heapptr) \ - AWAKEN_BQ(updclosure); \ - updateWithIndirection((StgClosure *)updclosure, \ - (StgClosure *)heapptr); +#ifdef SMP +#define UPD_REAL_IND(updclosure, ind_info, heapptr, and_then) \ + { \ + 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, ind_info, \ + (StgClosure *)updclosure, \ + (StgClosure *)heapptr, \ + and_then); \ + } +#else +#define UPD_REAL_IND(updclosure, ind_info, heapptr, and_then) \ + { \ + const StgInfoTable *info; \ + info = ((StgClosure *)updclosure)->header.info; \ + AWAKEN_BQ(info,updclosure); \ + updateWithIndirection(((StgClosure *)updclosure)->header.info, ind_info, \ + (StgClosure *)updclosure, \ + (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) \ - AWAKEN_BQ(updclosure); \ - updateWithPermIndirection((StgClosure *)updclosure, \ - (StgClosure *)heapptr); +#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,&stg_IND_info, \ + (StgClosure *)updclosure, \ + (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 /* ----------------------------------------------------------------------------- Awaken any threads waiting on this computation -------------------------------------------------------------------------- */ +#define AWAKEN_BQ_CLOSURE(closure) \ + { \ + const StgInfoTable *info; \ + info = ((StgClosure *)closure)->header.info; \ + AWAKEN_BQ(info,closure); \ + } + +#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 ... 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(closure) \ - if (closure->header.info == &BLACKHOLE_BQ_info) { \ - StgTSO *bq = ((StgBlockingQueue *)closure)->blocking_queue;\ - if (bq != (StgTSO *)&END_TSO_QUEUE_closure) { \ - STGCALL1(awakenBlockedQueue, bq); \ - } \ +#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); \ + } -/* ----------------------------------------------------------------------------- +#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 */ + +/* ------------------------------------------------------------------------- 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 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 = stgCast(StgUpdateFrame*,Sp + (Sp_offset)) - 1; \ - SET_INFO(__frame,stgCast(StgInfoTable*,&Upd_frame_info)); \ - __frame->link = Su; \ + __frame = (StgUpdateFrame *)(Sp + (Sp_offset)) - 1; \ + SET_INFO(__frame, (StgInfoTable *)&stg_upd_frame_info); \ __frame->updatee = (StgClosure *)(target); \ PUSH_STD_CCCS(__frame); \ - Su = __frame; \ } /* ----------------------------------------------------------------------------- @@ -112,27 +274,20 @@ extern DLL_IMPORT_DATA const StgPolyInfoTable Upd_frame_info; extern void newCAF(StgClosure*); -#define UPD_CAF(cafptr, bhptr) \ - { \ - SET_INFO((StgInd *)cafptr,(const StgInfoTable*)&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*)&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 */