Use message-passing to implement throwTo in the RTS
[ghc-hetmet.git] / includes / rts / storage / TSO.h
index 7cb2459..e2015f2 100644 (file)
@@ -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,8 @@ typedef struct {
 /* Reason for thread being blocked. See comment above struct StgTso_. */
 typedef union {
   StgClosure *closure;
-  struct StgTSO_ *tso;
+  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;
@@ -88,15 +88,35 @@ typedef struct StgTSO_ {
          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 +125,7 @@ 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;
 
 #ifdef TICKY_TICKY
     /* TICKY-specific stuff would go here. */
@@ -149,7 +169,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 +177,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 +191,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