X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=includes%2Frts%2Fstorage%2FTSO.h;h=e07be88ac51858153b239f07482751b9fb3062d0;hp=7cb245909f29e9426282afacad3f7ace4c6f8ee8;hb=5d52d9b64c21dcf77849866584744722f8121389;hpb=a2a67cd520b9841114d69a87a423dabcb3b4368e diff --git a/includes/rts/storage/TSO.h b/includes/rts/storage/TSO.h index 7cb2459..e07be88 100644 --- a/includes/rts/storage/TSO.h +++ b/includes/rts/storage/TSO.h @@ -25,7 +25,6 @@ typedef struct { */ typedef StgWord32 StgThreadID; -#define tsoDirty(tso) ((tso)->flags & TSO_DIRTY) #define tsoLocked(tso) ((tso)->flags & TSO_LOCKED) /* @@ -47,7 +46,9 @@ typedef struct { /* Reason for thread being blocked. See comment above struct StgTso_. */ typedef union { StgClosure *closure; - struct StgTSO_ *tso; + 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; @@ -78,25 +79,50 @@ typedef struct StgTSO_ { */ struct StgTSO_* _link; /* + Currently used for linking TSOs on: + * cap->run_queue_{hd,tl} + * MVAR queue + * (non-THREADED_RTS); the blocked_queue + * and pointing to the relocated version of a ThreadRelocated + 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 - StgWord16 what_next; /* Values defined in Constants.h */ - StgWord16 why_blocked; /* Values defined in Constants.h */ - StgWord32 flags; + StgWord dirty; /* non-zero => dirty */ + /* + * The tso->dirty flag indicates that this TSO's stack should be + * scanned during garbage collection. It also indicates that this + * TSO is on the mutable list. + * + * NB. The dirty flag gets a word to itself, so that it can be set + * safely by multiple threads simultaneously (the flags field is + * not safe for this purpose; see #3429). It is harmless for the + * TSO to be on the mutable list multiple times. + * + * 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; // Values defined in Constants.h StgTSOBlockInfo block_info; StgThreadID id; int saved_errno; - struct Task_* bound; + struct InCall_* bound; struct Capability_* cap; struct StgTRecHeader_ * trec; /* STM transaction record */ @@ -105,7 +131,13 @@ typedef struct StgTSO_ { exceptions. In order to access this field, the TSO must be locked using lockClosure/unlockClosure (see SMP.h). */ - 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. */ @@ -132,6 +164,18 @@ typedef struct StgTSO_ { void dirty_TSO (Capability *cap, StgTSO *tso); void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); +// Apply to a TSO before looking at it if you are not sure whether it +// might be ThreadRelocated or not (basically, that's most of the time +// unless the TSO is the current TSO). +// +INLINE_HEADER StgTSO * deRefTSO(StgTSO *tso) +{ + while (tso->what_next == ThreadRelocated) { + tso = tso->_link; + } + return tso; +} + /* ----------------------------------------------------------------------------- Invariants: @@ -149,7 +193,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 @@ -157,7 +201,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 @@ -171,7 +215,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