} StgTSOStatBuf;
/*
- * GRAN: We distinguish between the various classes of threads in
- * the system.
- */
-typedef enum {
- AdvisoryPriority,
- MandatoryPriority,
- RevalPriority
-} StgThreadPriority;
-
-/*
* PROFILING info in a TSO
*/
typedef struct {
} StgTSOProfInfo;
/*
- * PAR info in a TSO
- */
-typedef StgTSOStatBuf StgTSOParInfo;
-
-/*
- * DIST info in a TSO
- */
-typedef struct {
- StgThreadPriority priority;
- StgInt revalTid; /* ToDo: merge both into 1 word */
- StgInt revalSlot;
-} StgTSODistInfo;
-
-/*
- * GRAN info in a TSO
- */
-typedef StgTSOStatBuf StgTSOGranInfo;
-
-/*
* There is no TICKY info in a TSO at this time.
*/
*/
typedef StgWord32 StgThreadID;
-/*
- * Flags for the tso->flags field.
- *
- * The TSO_DIRTY flag indicates that this TSO's stack should be
- * scanned during garbage collection. The link field of a TSO is
- * always scanned, so we don't have to dirty a TSO just for linking
- * it on a different list.
- *
- * TSO_DIRTY is set by
- * - schedule(), just before running a thread,
- * - raiseAsync(), because it modifies a thread's stack
- * - resumeThread(), just before running the thread again
- * and unset by the garbage collector (only).
- */
-#define TSO_DIRTY 1
-
-/*
- * TSO_LOCKED is set when a TSO is locked to a particular Capability.
- */
-#define TSO_LOCKED 2
-
#define tsoDirty(tso) ((tso)->flags & TSO_DIRTY)
#define tsoLocked(tso) ((tso)->flags & TSO_LOCKED)
StgWord target;
} StgTSOBlockInfo;
+
/*
* TSOs live on the heap, and therefore look just like heap objects.
* Large TSOs will live in their own "block group" allocated by the
typedef struct StgTSO_ {
StgHeader header;
- struct StgTSO_* link; /* Links threads onto blocking queues */
+ /* The link field, for linking threads together in lists (e.g. the
+ run queue on a Capability.
+ */
+ struct StgTSO_* _link;
+ /*
+ 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 */
StgWord16 what_next; /* Values defined in Constants.h */
StgWord16 why_blocked; /* Values defined in Constants.h */
StgWord32 flags;
StgTSOBlockInfo block_info;
- struct StgTSO_* blocked_exceptions;
StgThreadID id;
int saved_errno;
struct Task_* 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).
+ */
+ struct StgTSO_ * blocked_exceptions;
+
#ifdef TICKY_TICKY
/* TICKY-specific stuff would go here. */
#endif
#ifdef PROFILING
StgTSOProfInfo prof;
#endif
-#ifdef PAR
- StgTSOParInfo par;
-#endif
-#ifdef GRAN
- StgTSOGranInfo gran;
-#endif
-#ifdef DIST
- StgTSODistInfo dist;
+#ifdef mingw32_HOST_OS
+ StgWord32 saved_winerror;
#endif
/* The thread stack... */
} StgTSO;
/* -----------------------------------------------------------------------------
+ functions
+ -------------------------------------------------------------------------- */
+
+extern void dirty_TSO (Capability *cap, StgTSO *tso);
+extern void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target);
+
+/* -----------------------------------------------------------------------------
Invariants:
An active thread has the following properties:
(tso->sp is left pointing at the top word on the stack so that
the return value or exception will be retained by a GC).
- tso->blocked_exceptions is either:
-
- NULL if async exceptions are unblocked.
-
- END_TSO_QUEUE if async exceptions are blocked, but no threads
- are currently waiting to deliver.
-
- (StgTSO *)tso if threads are currently awaiting delivery of
- exceptions to this thread.
-
The 2 cases BlockedOnGA and BlockedOnGA_NoSend are needed in a GUM
setup only. They mark a TSO that has entered a FETCH_ME or
FETCH_ME_BQ closure, respectively; only the first TSO hitting the
#define TSO_STRUCT_SIZEW (TSO_STRUCT_SIZE / sizeof(W_))
-
/* this is the NIL ptr for a TSO queue (e.g. runnable queue) */
-#if IN_STG_CODE
-#define END_TSO_QUEUE (stg_END_TSO_QUEUE_closure)
-#else
#define END_TSO_QUEUE ((StgTSO *)(void*)&stg_END_TSO_QUEUE_closure)
-#endif
-
-#if defined(PAR) || defined(GRAN)
-/* this is the NIL ptr for a blocking queue */
-# define END_BQ_QUEUE ((StgBlockingQueueElement *)(void*)&stg_END_TSO_QUEUE_closure)
-/* this is the NIL ptr for a blocked fetch queue (as in PendingFetches in GUM) */
-# define END_BF_QUEUE ((StgBlockedFetch *)(void*)&stg_END_TSO_QUEUE_closure)
-#endif
-/* ToDo?: different name for end of sleeping queue ? -- HWL */
#endif /* TSO_H */