X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=includes%2Frts%2Fstorage%2FTSO.h;h=04e673fb12a51d4728ad59507c9753cfc638c0ce;hb=02c76a04093613960f8016fba07a8a6e59e7cd3b;hp=e8d97c5ce0a53402ab16ddd33f2ea375574922e0;hpb=7effbbbbdfe7eb05c6402fa9337e358e7e9fadde;p=ghc-hetmet.git diff --git a/includes/rts/storage/TSO.h b/includes/rts/storage/TSO.h index e8d97c5..04e673f 100644 --- a/includes/rts/storage/TSO.h +++ b/includes/rts/storage/TSO.h @@ -46,7 +46,10 @@ typedef struct { /* Reason for thread being blocked. See comment above struct StgTso_. */ typedef union { StgClosure *closure; - struct StgTSO_ *tso; + StgTSO *prev; // a back-link when the TSO is on the run queue (NotBlocked) + struct MessageBlackHole_ *bh; + struct MessageThrowTo_ *throwto; + struct MessageWakeup_ *wakeup; StgInt fd; /* StgInt instead of int, so that it's the same size as the ptrs */ #if defined(mingw32_HOST_OS) StgAsyncIOResult *async_result; @@ -77,19 +80,28 @@ typedef struct StgTSO_ { */ struct StgTSO_* _link; /* + Currently used for linking TSOs on: + * cap->run_queue_{hd,tl} + * (non-THREADED_RTS); the blocked_queue + * and pointing to the next chunk for a ThreadOldStack + NOTE!!! do not modify _link directly, it is subject to a write barrier for generational GC. Instead use the setTSOLink() function. Exceptions to this rule are: * setting the link field to END_TSO_QUEUE - * putting a TSO on the blackhole_queue * setting the link field of the currently running TSO, as it will already be dirty. */ - struct StgTSO_* global_link; /* Links all threads together */ + struct StgTSO_* global_link; // Links threads on the + // generation->threads lists - StgWord dirty; /* non-zero => dirty */ + /* + * The thread's stack + */ + struct StgStack_ *stackobj; + /* * The tso->dirty flag indicates that this TSO's stack should be * scanned during garbage collection. It also indicates that this @@ -102,28 +114,30 @@ typedef struct StgTSO_ { * * tso->dirty is set by dirty_TSO(), and unset by the garbage * collector (only). - * - * The link field has a separate dirty bit of its own, namely the - * bit TSO_LINK_DIRTY in the tso->flags field, set by - * setTSOLink(). */ - StgWord16 what_next; /* Values defined in Constants.h */ - StgWord16 why_blocked; /* Values defined in Constants.h */ - StgWord32 flags; + StgWord16 what_next; // Values defined in Constants.h + StgWord16 why_blocked; // Values defined in Constants.h + StgWord32 flags; // Values defined in Constants.h StgTSOBlockInfo block_info; StgThreadID id; - int saved_errno; + StgWord32 saved_errno; + StgWord32 dirty; /* non-zero => dirty */ struct InCall_* bound; struct Capability_* cap; + struct StgTRecHeader_ * trec; /* STM transaction record */ /* - A list of threads blocked on this TSO waiting to throw - exceptions. In order to access this field, the TSO must be - locked using lockClosure/unlockClosure (see SMP.h). + * A list of threads blocked on this TSO waiting to throw exceptions. */ - struct StgTSO_ * blocked_exceptions; + struct MessageThrowTo_ * blocked_exceptions; + + /* + * A list of StgBlockingQueue objects, representing threads + * blocked on thunks that are under evaluation by this thread. + */ + struct StgBlockingQueue_ *bq; #ifdef TICKY_TICKY /* TICKY-specific stuff would go here. */ @@ -135,20 +149,45 @@ typedef struct StgTSO_ { StgWord32 saved_winerror; #endif - /* The thread stack... */ - StgWord32 stack_size; /* stack size in *words* */ - StgWord32 max_stack_size; /* maximum stack size in *words* */ - StgPtr sp; - - StgWord stack[FLEXIBLE_ARRAY]; + /* + * sum of the sizes of all stack chunks (in words), used to decide + * whether to throw the StackOverflow exception when the stack + * overflows, or whether to just chain on another stack chunk. + * + * Note that this overestimates the real stack size, because each + * chunk will have a gap at the end, of +RTS -kb words. + * This means stack overflows are not entirely accurate, because + * the more gaps there are, the sooner the stack will run into the + * hard +RTS -K limit. + */ + StgWord32 tot_stack_size; + } *StgTSOPtr; +typedef struct StgStack_ { + StgHeader header; + StgWord32 stack_size; // stack size in *words* + StgWord32 dirty; // non-zero => dirty + StgPtr sp; // current stack pointer + StgWord stack[FLEXIBLE_ARRAY]; +} StgStack; + +// Calculate SpLim from a TSO (reads tso->stackobj, but no fields from +// the stackobj itself). +INLINE_HEADER StgPtr tso_SpLim (StgTSO* tso) +{ + return tso->stackobj->stack + RESERVED_STACK_WORDS; +} + /* ----------------------------------------------------------------------------- functions -------------------------------------------------------------------------- */ void dirty_TSO (Capability *cap, StgTSO *tso); void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); +void setTSOPrev (Capability *cap, StgTSO *tso, StgTSO *target); + +void dirty_STACK (Capability *cap, StgStack *stack); /* ----------------------------------------------------------------------------- Invariants: @@ -167,7 +206,7 @@ void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); tso->why_blocked tso->block_info location ---------------------------------------------------------------------- - NotBlocked NULL runnable_queue, or running + NotBlocked END_TSO_QUEUE runnable_queue, or running BlockedOnBlackHole the BLACKHOLE blackhole_queue @@ -175,7 +214,7 @@ void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); BlockedOnSTM END_TSO_QUEUE STM wait queue(s) - BlockedOnException the TSO TSO->blocked_exception + BlockedOnMsgThrowTo MessageThrowTo * TSO->blocked_exception BlockedOnRead NULL blocked_queue BlockedOnWrite NULL blocked_queue @@ -189,7 +228,6 @@ void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); tso->what_next == ThreadComplete or ThreadKilled tso->link == (could be on some queue somewhere) - tso->su == tso->stack + tso->stack_size tso->sp == tso->stack + tso->stack_size - 1 (i.e. top stack word) tso->sp[0] == return value of thread, if what_next == ThreadComplete, exception , if what_next == ThreadKilled @@ -206,18 +244,6 @@ void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); ---------------------------------------------------------------------------- */ -/* Workaround for a bug/quirk in gcc on certain architectures. - * symptom is that (&tso->stack - &tso->header) /= sizeof(StgTSO) - * in other words, gcc pads the structure at the end. - */ - -extern StgTSO dummy_tso; - -#define TSO_STRUCT_SIZE \ - ((char *)&dummy_tso.stack - (char *)&dummy_tso.header) - -#define TSO_STRUCT_SIZEW (TSO_STRUCT_SIZE / sizeof(W_)) - /* this is the NIL ptr for a TSO queue (e.g. runnable queue) */ #define END_TSO_QUEUE ((StgTSO *)(void*)&stg_END_TSO_QUEUE_closure)