X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=includes%2Frts%2Fstorage%2FTSO.h;h=0e9883f1a6b39e6a9fc4212dcb24070686300647;hb=f6ee1f315a7e7069b21a993fb058e00d06b73487;hp=7cb245909f29e9426282afacad3f7ace4c6f8ee8;hpb=a2a67cd520b9841114d69a87a423dabcb3b4368e;p=ghc-hetmet.git diff --git a/includes/rts/storage/TSO.h b/includes/rts/storage/TSO.h index 7cb2459..0e9883f 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,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; @@ -78,25 +80,49 @@ 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 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. */ @@ -131,6 +163,19 @@ typedef struct StgTSO_ { void dirty_TSO (Capability *cap, StgTSO *tso); void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); +void setTSOPrev (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 +194,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 +202,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 +216,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