Commits

Armin Rigo committed e0504b2

Update to the latest version of stmimpl.rst.

Comments (0)

Files changed (1)

 /************************************************************/
 
 #define ABORT_REASONS 4
-#define SPINLOOP_REASONS 3
+#define SPINLOOP_REASONS 4
 
 struct tx_descriptor {
   jmp_buf *setjmp_buf;
   L->h_tid |= GCFLAG_LOCAL_COPY;
   L->h_revision = (revision_t)R;     /* back-reference to the original */
   g2l_insert(&d->global_to_local, R, L);
+  gcptrlist_insert(&d->list_of_read_objects, R);
   return L;
 }
 
     }
 }
 
-static _Bool ValidateDuringTransaction(struct tx_descriptor *d)
+static _Bool ValidateDuringTransaction(struct tx_descriptor *d,
+                                       _Bool during_commit)
 {
-
   long i, size = d->list_of_read_objects.size;
   gcptr *items = d->list_of_read_objects.items;
-  wlog_t *item;
 
   for (i=0; i<size; i++)
     {
       if (!(v & 1))               // "is a pointer", i.e.
         return 0;                 //   "has a more recent revision"
       if (v >= LOCKED)            // locked
-        goto retry;
+        {
+          if (!during_commit)
+            {
+              assert(v != d->my_lock);    // we don't hold any lock
+              SpinLoop(3);
+              goto retry;
+            }
+          else
+            {
+              if (v != d->my_lock)         // not locked by me: conflict
+                return 0;
+            }
+        }
     }
-  G2L_LOOP_FORWARD(d->global_to_local, item)
-    {
-      gcptr R = item->addr;
-      revision_t v;
-    retry2:
-      v = R->h_revision;
-      if (!(v & 1))               // "is a pointer", i.e.
-        return 0;                 //   "has a more recent revision"
-      if (v >= LOCKED)            // locked
-        goto retry2;
-    } G2L_LOOP_END;
   return 1;
 }
 
 static void ValidateNow(struct tx_descriptor *d)
 {
-  assert(!is_inevitable(d));
   d->start_time = GetGlobalCurTime(d);   // copy from the global time
-  if (!ValidateDuringTransaction(d))
+  if (!ValidateDuringTransaction(d, 0))
     AbortTransaction(1);
 }
 
-static _Bool ValidateDuringCommit(struct tx_descriptor *d)
-{
-  long i, size = d->list_of_read_objects.size;
-  gcptr *items = d->list_of_read_objects.items;
-  revision_t my_lock = d->my_lock;
-
-  for (i=0; i<size; i++)
-    {
-      gcptr R = items[i];
-      revision_t v = R->h_revision;
-      if (!(v & 1))               // "is a pointer", i.e.
-        return 0;                 //   "has a more recent revision"
-      if (v >= LOCKED)            // locked
-        if (v != my_lock)         // and not by me
-          return 0;               // XXX abort or spinloop??
-    }
-  return 1;
-}
-
 /************************************************************/
 
 static void SpinLoop(int num)
         }
       // validate (but skip validation if nobody else committed)
       if (cur_time != d->start_time)
-        if (!ValidateDuringCommit(d))
+        if (!ValidateDuringTransaction(d, 1))
           AbortTransaction(2);
     }
   UpdateChainHeads(d, cur_time);
   if (d->start_time != cur_time)
     {
       d->start_time = cur_time;
-      if (!ValidateDuringTransaction(d))
+      if (!ValidateDuringTransaction(d, 0))
         {
           global_cur_time = cur_time;   // must restore the old value
           inev_mutex_release();