remove empty dir
[ghc-hetmet.git] / ghc / includes / Closures.h
index 066fe91..3df208c 100644 (file)
@@ -35,6 +35,23 @@ typedef struct {
 } StgGranHeader;
 
 /* -----------------------------------------------------------------------------
+   The SMP header
+   
+   A thunk has a padding word to take the updated value.  This is so
+   that the update doesn't overwrite the payload, so we can avoid
+   needing to lock the thunk during entry and update.
+   
+   Note: this doesn't apply to THUNK_STATICs, which have no payload.
+
+   Note: we leave this padding word in all ways, rather than just SMP,
+   so that we don't have to recompile all our libraries for SMP.
+   -------------------------------------------------------------------------- */
+
+typedef struct {
+    StgWord pad;
+} StgSMPThunkHeader;
+
+/* -----------------------------------------------------------------------------
    The full fixed-size closure header
 
    The size of the fixed header is the sum of the optional parts plus a single
@@ -42,15 +59,28 @@ typedef struct {
    -------------------------------------------------------------------------- */
 
 typedef struct {
-       const struct _StgInfoTable* info;
+    const struct _StgInfoTable* info;
 #ifdef PROFILING
-       StgProfHeader         prof;
+    StgProfHeader         prof;
 #endif
 #ifdef GRAN
-       StgGranHeader         gran;
+    StgGranHeader         gran;
 #endif
 } StgHeader;
 
+typedef struct {
+    const struct _StgInfoTable* info;
+#ifdef PROFILING
+    StgProfHeader         prof;
+#endif
+#ifdef GRAN
+    StgGranHeader         gran;
+#endif
+    StgSMPThunkHeader     smp;
+} StgThunkHeader;
+
+#define THUNK_EXTRA_HEADER_W (sizeofW(StgThunkHeader)-sizeofW(StgHeader))
+
 /* -----------------------------------------------------------------------------
    Closure Types
 
@@ -67,7 +97,12 @@ struct StgClosure_ {
 };
 
 typedef struct {
-    StgHeader   header;
+    StgThunkHeader  header;
+    struct StgClosure_ *payload[FLEXIBLE_ARRAY];
+} StgThunk;
+
+typedef struct {
+    StgThunkHeader   header;
     StgClosure *selectee;
 } StgSelector;
 
@@ -79,11 +114,16 @@ typedef struct {
     StgClosure *payload[FLEXIBLE_ARRAY];
 } StgPAP;
 
-/* AP closures have the same layout, for convenience */
-typedef StgPAP StgAP;
+typedef struct {
+    StgThunkHeader   header;
+    StgHalfWord arity;         /* zero if it is an AP */
+    StgHalfWord n_args;
+    StgClosure *fun;           /* really points to a fun */
+    StgClosure *payload[FLEXIBLE_ARRAY];
+} StgAP;
 
 typedef struct {
-    StgHeader   header;
+    StgThunkHeader   header;
     StgWord     size;                    /* number of words in payload */
     StgClosure *fun;
     StgClosure *payload[FLEXIBLE_ARRAY]; /* contains a chunk of *stack* */
@@ -148,11 +188,6 @@ typedef struct {
   StgHeader  header;
 } StgRetry;
 
-typedef struct _StgForeignObj {
-  StgHeader      header;
-  StgAddr        data;         /* pointer to data in non-haskell-land */
-} StgForeignObj;
-  
 typedef struct _StgStableName {
   StgHeader      header;
   StgWord        sn;
@@ -286,6 +321,7 @@ typedef struct {
   StgClosure*     value;
 } StgMVar;
 
+
 /* STM data structures
  *
  *  StgTVar defines the only type that can be updated through the STM
@@ -302,6 +338,11 @@ typedef struct {
  *   - In StgTRecHeader, it might be worthwhile having separate chunks
  *     of read-only and read-write locations.  This would save a
  *     new_value field in the read-only locations.
+ *
+ *   - In StgAtomicallyFrame, we could combine the waiting bit into
+ *     the header (maybe a different info tbl for a waiting transaction).
+ *     This means we can specialise the code for the atomically frame
+ *     (it immediately switches on frame->waiting anyway).
  */
 
 typedef struct StgTVarWaitQueue_ {
@@ -313,8 +354,11 @@ typedef struct StgTVarWaitQueue_ {
 
 typedef struct {
   StgHeader                  header;
-  StgClosure                *current_value;
-  StgTVarWaitQueue          *first_wait_queue_entry;
+  StgClosure                *volatile current_value;
+  StgTVarWaitQueue          *volatile first_wait_queue_entry;
+#if defined(THREADED_RTS)
+  StgInt                     volatile num_updates;
+#endif
 } StgTVar;
 
 /* new_value == expected_value for read-only accesses */
@@ -323,9 +367,12 @@ typedef struct {
   StgTVar                   *tvar;
   StgClosure                *expected_value;
   StgClosure                *new_value; 
+#if defined(THREADED_RTS)
+  StgInt                     num_updates;
+#endif
 } TRecEntry;
 
-#define TREC_CHUNK_NUM_ENTRIES 256
+#define TREC_CHUNK_NUM_ENTRIES 16
 
 typedef struct StgTRecChunk_ {
   StgHeader                  header;
@@ -336,8 +383,7 @@ typedef struct StgTRecChunk_ {
 
 typedef enum { 
   TREC_ACTIVE,        /* Transaction in progress, outcome undecided */
-  TREC_CANNOT_COMMIT, /* Transaction in progress, inconsistent writes performed */
-  TREC_MUST_ABORT,    /* Transaction in progress, inconsistent / out of date reads */
+  TREC_CONDEMNED,     /* Transaction in progress, inconsistent / out of date reads */
   TREC_COMMITTED,     /* Transaction has committed, now updating tvars */
   TREC_ABORTED,       /* Transaction has aborted, now reverting tvars */
   TREC_WAITING,       /* Transaction currently waiting */
@@ -352,7 +398,6 @@ typedef struct StgTRecHeader_ {
 
 typedef struct {
     StgHeader   header;
-    StgBool     waiting;
     StgClosure *code;
 } StgAtomicallyFrame;