propagate the result of atomically properly (fixes #3049)
[ghc-hetmet.git] / includes / Closures.h
index 3df208c..eb5d1ed 100644 (file)
@@ -27,14 +27,6 @@ typedef struct {
 } StgProfHeader;
 
 /* -----------------------------------------------------------------------------
-   The GranSim header
-   -------------------------------------------------------------------------- */
-
-typedef struct {
-  StgWord procs; /* bitmask indicating on which PEs this closure resides */
-} StgGranHeader;
-
-/* -----------------------------------------------------------------------------
    The SMP header
    
    A thunk has a padding word to take the updated value.  This is so
@@ -63,9 +55,6 @@ typedef struct {
 #ifdef PROFILING
     StgProfHeader         prof;
 #endif
-#ifdef GRAN
-    StgGranHeader         gran;
-#endif
 } StgHeader;
 
 typedef struct {
@@ -73,9 +62,6 @@ typedef struct {
 #ifdef PROFILING
     StgProfHeader         prof;
 #endif
-#ifdef GRAN
-    StgGranHeader         gran;
-#endif
     StgSMPThunkHeader     smp;
 } StgThunkHeader;
 
@@ -174,11 +160,6 @@ typedef struct {
 } StgStopFrame;  
 
 typedef struct {
-    StgHeader   header;
-    StgClosure *evacuee;
-} StgEvacuated;
-
-typedef struct {
   StgHeader header;
   StgWord data;
 } StgIntCharlikeClosure;
@@ -195,6 +176,7 @@ typedef struct _StgStableName {
 
 typedef struct _StgWeak {      /* Weak v */
   StgHeader header;
+  StgClosure *cfinalizer;
   StgClosure *key;
   StgClosure *value;           /* v */
   StgClosure *finalizer;
@@ -232,7 +214,6 @@ typedef struct {
     StgArrWords   *instrs;     /* a pointer to an ArrWords */
     StgArrWords   *literals;   /* a pointer to an ArrWords */
     StgMutArrPtrs *ptrs;       /* a pointer to a  MutArrPtrs */
-    StgArrWords   *itbls;      /* a pointer to an ArrWords */
     StgHalfWord   arity;        /* arity of this BCO */
     StgHalfWord   size;         /* size of this BCO (in words) */
     StgWord       bitmap[FLEXIBLE_ARRAY];  /* an StgLargeBitmap */
@@ -331,7 +312,7 @@ typedef struct {
  *  space for these data structures at the cost of more complexity in the
  *  implementation:
  *
- *   - In StgTVar, current_value and first_wait_queue_entry could be held in
+ *   - In StgTVar, current_value and first_watch_queue_entry could be held in
  *     the same field: if any thread is waiting then its expected_value for
  *     the tvar is the current value.  
  *
@@ -345,24 +326,33 @@ typedef struct {
  *     (it immediately switches on frame->waiting anyway).
  */
 
-typedef struct StgTVarWaitQueue_ {
+typedef struct StgTRecHeader_ StgTRecHeader;
+
+typedef struct StgTVarWatchQueue_ {
   StgHeader                  header;
-  struct StgTSO_            *waiting_tso;
-  struct StgTVarWaitQueue_  *next_queue_entry;
-  struct StgTVarWaitQueue_  *prev_queue_entry;
-} StgTVarWaitQueue;
+  StgClosure                *closure; // StgTSO or StgAtomicInvariant
+  struct StgTVarWatchQueue_ *next_queue_entry;
+  struct StgTVarWatchQueue_ *prev_queue_entry;
+} StgTVarWatchQueue;
 
 typedef struct {
   StgHeader                  header;
   StgClosure                *volatile current_value;
-  StgTVarWaitQueue          *volatile first_wait_queue_entry;
+  StgTVarWatchQueue         *volatile first_watch_queue_entry;
 #if defined(THREADED_RTS)
   StgInt                     volatile num_updates;
 #endif
 } StgTVar;
 
+typedef struct {
+  StgHeader      header;
+  StgClosure    *code;
+  StgTRecHeader *last_execution;
+  StgWord        lock;
+} StgAtomicInvariant;
+
 /* new_value == expected_value for read-only accesses */
-/* new_value is a StgTVarWaitQueue entry when trec in state TREC_WAITING */
+/* new_value is a StgTVarWatchQueue entry when trec in state TREC_WAITING */
 typedef struct {
   StgTVar                   *tvar;
   StgClosure                *expected_value;
@@ -389,92 +379,39 @@ typedef enum {
   TREC_WAITING,       /* Transaction currently waiting */
 } TRecState;
 
-typedef struct StgTRecHeader_ {
+typedef struct StgInvariantCheckQueue_ {
+  StgHeader                       header;
+  StgAtomicInvariant             *invariant;
+  StgTRecHeader                  *my_execution;
+  struct StgInvariantCheckQueue_ *next_queue_entry;
+} StgInvariantCheckQueue;
+
+struct StgTRecHeader_ {
   StgHeader                  header;
   TRecState                  state;
   struct StgTRecHeader_     *enclosing_trec;
   StgTRecChunk              *current_chunk;
-} StgTRecHeader;
+  StgInvariantCheckQueue    *invariants_to_check;
+};
 
 typedef struct {
-    StgHeader   header;
-    StgClosure *code;
+  StgHeader   header;
+  StgClosure *code;
+  StgTVarWatchQueue *next_invariant_to_check;
+  StgClosure *result;
 } StgAtomicallyFrame;
 
 typedef struct {
-    StgHeader   header;
-    StgClosure *handler;
+  StgHeader   header;
+  StgClosure *code;
+  StgClosure *handler;
 } StgCatchSTMFrame;
 
 typedef struct {
-    StgHeader      header;
-    StgBool        running_alt_code;
-    StgClosure    *first_code;
-    StgClosure    *alt_code;
-    StgTRecHeader *first_code_trec;
+  StgHeader      header;
+  StgBool        running_alt_code;
+  StgClosure    *first_code;
+  StgClosure    *alt_code;
 } StgCatchRetryFrame;
 
-#if defined(PAR) || defined(GRAN)
-/*
-  StgBlockingQueueElement is a ``collective type'' representing the types
-  of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
-  StgBlockedFetch.  (StgRBHSave can only appear at the end of a blocking
-  queue).  Logically, this is a union type, but defining another struct
-  with a common layout is easier to handle in the code.  
-  Note that in the standard setup only StgTSOs can be on a blocking queue.
-  This is one of the main reasons for slightly different code in files
-  such as Schedule.c.
-*/
-typedef struct StgBlockingQueueElement_ {
-  StgHeader                         header;
-  struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
-  struct StgClosure_               *payload[FLEXIBLE_ARRAY];/* contents of the closure */
-} StgBlockingQueueElement;
-
-/* only difference to std code is type of the elem in the BQ */
-typedef struct StgBlockingQueue_ {
-  StgHeader                 header;
-  struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
-} StgBlockingQueue;
-
-/* this closure is hanging at the end of a blocking queue in (see RBH.c) */
-typedef struct StgRBHSave_ {
-  StgHeader    header;
-  StgClosure  *payload[FLEXIBLE_ARRAY];     /* 2 words ripped out of the guts of the */
-} StgRBHSave;                  /*  closure holding the blocking queue */
-typedef struct StgRBH_ {
-  StgHeader                         header;
-  struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
-} StgRBH;
-
-#endif
-
-#if defined(PAR)
-/* global indirections aka FETCH_ME closures */
-typedef struct StgFetchMe_ {
-  StgHeader              header;
-  globalAddr            *ga;        /* ptr to unique id for a closure */
-} StgFetchMe;
-
-/* same contents as an ordinary StgBlockingQueue */
-typedef struct StgFetchMeBlockingQueue_ {
-  StgHeader                          header;
-  struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
-} StgFetchMeBlockingQueue;
-
-/* This is an entry in a blocking queue. It indicates a fetch request from a 
-   TSO on another PE demanding the value of this closur. Note that a
-   StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
-   updated with the result, the result will be sent back (the PE is encoded
-   in the globalAddr) and the StgBlockedFetch closure will be nuked.
-*/
-typedef struct StgBlockedFetch_ {
-  StgHeader                         header;
-  struct StgBlockingQueueElement_  *link;     /* next elem in the BQ */
-  StgClosure                       *node;     /* node to fetch */
-  globalAddr                        ga;       /* where to send the result to */
-} StgBlockedFetch;                            /* NB: not just a ptr to a GA */
-#endif
-
 #endif /* CLOSURES_H */