X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FClosures.h;h=d160ac5901687b0c6e59e6e9d850e9aedc08ebe9;hb=6fbbd40feed0d23eb1d2504b70054ec001e95bd9;hp=2f4d8652b347d044a5617a6745b5f3e7885abb10;hpb=b3f530814c15886a7a010ed871bb1f054a3918b3;p=ghc-hetmet.git diff --git a/ghc/includes/Closures.h b/ghc/includes/Closures.h index 2f4d865..d160ac5 100644 --- a/ghc/includes/Closures.h +++ b/ghc/includes/Closures.h @@ -1,7 +1,6 @@ /* ---------------------------------------------------------------------------- - * $Id: Closures.h,v 1.33 2003/03/24 14:46:53 simonmar Exp $ * - * (c) The GHC Team, 1998-1999 + * (c) The GHC Team, 1998-2004 * * Closures * @@ -52,8 +51,6 @@ typedef struct { #endif } StgHeader; -#define FIXED_HS (sizeof(StgHeader)) - /* ----------------------------------------------------------------------------- Closure Types @@ -233,11 +230,53 @@ typedef struct { #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \ / BITS_IN(StgWord)) -/* Dynamic stack frames - these have a liveness mask in the object - * itself, rather than in the info table. Useful for generic heap - * check code. See StgMacros.h, HEAP_CHK_GEN(). - */ - +/* ----------------------------------------------------------------------------- + Dynamic stack frames for generic heap checks. + + These generic heap checks are slow, but have the advantage of being + usable in a variety of situations. + + The one restriction is that any relevant SRTs must already be pointed + to from the stack. The return address doesn't need to have an info + table attached: hence it can be any old code pointer. + + The liveness mask contains a 1 at bit n, if register Rn contains a + non-pointer. The contents of all 8 vanilla registers are always saved + on the stack; the liveness mask tells the GC which ones contain + pointers. + + Good places to use a generic heap check: + + - case alternatives (the return address with an SRT is already + on the stack). + + - primitives (no SRT required). + + The stack frame layout for a RET_DYN is like this: + + some pointers |-- RET_DYN_PTRS(liveness) words + some nonpointers |-- RET_DYN_NONPTRS(liveness) words + + L1 \ + D1-2 |-- RET_DYN_NONPTR_REGS_SIZE words + F1-4 / + + R1-8 |-- RET_DYN_BITMAP_SIZE words + + return address \ + liveness mask |-- StgRetDyn structure + stg_gen_chk_info / + + we assume that the size of a double is always 2 pointers (wasting a + word when it is only one pointer, but avoiding lots of #ifdefs). + + See Liveness.h for the macros (RET_DYN_PTRS() etc.). + + NOTE: if you change the layout of RET_DYN stack frames, then you + might also need to adjust the value of RESERVED_STACK_WORDS in + Constants.h. + -------------------------------------------------------------------------- */ + typedef struct { const struct _StgInfoTable* info; StgWord liveness; @@ -269,6 +308,93 @@ typedef struct { StgClosure* value; } StgMVar; +/* STM data structures + * + * StgTVar defines the only type that can be updated through the STM + * interface. + * + * Note that various optimisations may be possible in order to use less + * space for these data structures at the cost of more complexity in the + * implementation: + * + * - In StgTVar, current_value and first_wait_queue_entry could be held in + * the same field: if any thread is waiting then its expected_value for + * the tvar is the current value. + * + * - In StgTRecHeader, it might be worthwhile having separate chunks + * of read-only and read-write locations. This would save a + * new_value field in the read-only locations. + */ + +typedef struct StgTVarWaitQueue_ { + StgHeader header; + struct StgTSO_ *waiting_tso; + StgMutClosure *mut_link; + struct StgTVarWaitQueue_ *next_queue_entry; + struct StgTVarWaitQueue_ *prev_queue_entry; +} StgTVarWaitQueue; + +typedef struct { + StgHeader header; + StgClosure *current_value; + StgMutClosure *mut_link; + StgTVarWaitQueue *first_wait_queue_entry; +} StgTVar; + +// new_value == expected_value for read-only accesses +// new_value is a StgTVarWaitQueue entry when trec in state TREC_WAITING +typedef struct { + StgTVar *tvar; + StgClosure *expected_value; + StgClosure *new_value; +} TRecEntry; + +#define TREC_CHUNK_NUM_ENTRIES 256 + +typedef struct StgTRecChunk_ { + StgHeader header; + struct StgTRecChunk_ *prev_chunk; + StgMutClosure *mut_link; + StgWord next_entry_idx; + TRecEntry entries[TREC_CHUNK_NUM_ENTRIES]; +} StgTRecChunk; + +typedef enum { + TREC_ACTIVE, // Transaction in progress, outcome undecided + TREC_CANNOT_COMMIT, // Transaction in progress, inconsistent writes performed + TREC_MUST_ABORT, // Transaction in progress, inconsistent / out of date reads + TREC_COMMITTED, // Transaction has committed, now updating tvars + TREC_ABORTED, // Transaction has aborted, now reverting tvars + TREC_WAITING, // Transaction currently waiting +} TRecState; + +typedef struct StgTRecHeader_ { + StgHeader header; + TRecState state; + StgMutClosure *mut_link; + struct StgTRecHeader_ *enclosing_trec; + StgTRecChunk *current_chunk; +} StgTRecHeader; + +typedef struct { + StgHeader header; + StgBool waiting; + StgClosure *code; +} StgAtomicallyFrame; + +typedef struct { + StgHeader header; + StgClosure *handler; +} StgCatchSTMFrame; + +typedef struct { + StgHeader header; + StgBool running_alt_code; + StgClosure *first_code; + StgClosure *alt_code; + StgTRecHeader *first_code_trec; +} StgCatchRetryFrame; + #if defined(PAR) || defined(GRAN) /* StgBlockingQueueElement is a ``collective type'' representing the types