Author: Armin Rigo <[email protected]>
Branch: stm-gc-2
Changeset: r63307:7cb672c3e357
Date: 2013-04-13 14:50 +0200
http://bitbucket.org/pypy/pypy/changeset/7cb672c3e357/

Log:    Restore the original support: when there is an inevitable
        transaction, other concurrent transactions may run until they
        attempt to commit.

diff --git a/rpython/translator/stm/src_stm/et.c 
b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -35,7 +35,6 @@
 /************************************************************/
 
 typedef Unsigned revision_t;
-#define INEVITABLE  ((revision_t)-1)
 #define LOCKED  ((revision_t)-0x10000)
 
 #include "atomic_ops.h"
@@ -70,7 +69,9 @@
   struct FXCache recent_reads_cache;
 };
 
-static volatile revision_t global_cur_time = 2;        /* always mult of 2 */
+/* 'global_cur_time' is normally a multiple of 2, except when we turn
+   a transaction inevitable: we then add 1 to it. */
+static volatile revision_t global_cur_time = 2;
 static volatile revision_t next_locked_value = LOCKED + 3;   /* always odd */
 static __thread struct tx_descriptor *thread_descriptor = NULL;
 
@@ -317,18 +318,8 @@
 
 static revision_t GetGlobalCurTime(struct tx_descriptor *d)
 {
-  revision_t t;
   assert(!is_inevitable(d));    // must not be myself inevitable
-  while (1)
-    {
-      t = global_cur_time;
-      if (t != INEVITABLE)
-        return t;
-      // there is another transaction that is inevitable
-      inev_mutex_acquire();     // wait until released
-      inev_mutex_release();
-      // retry
-    }
+  return global_cur_time & ~1;
 }
 
 static _Bool ValidateDuringTransaction(struct tx_descriptor *d,
@@ -659,7 +650,7 @@
     {
       // no-one else can have changed global_cur_time if I'm inevitable
       cur_time = d->start_time;
-      if (!bool_cas(&global_cur_time, INEVITABLE, cur_time + 2))
+      if (!bool_cas(&global_cur_time, cur_time + 1, cur_time + 2))
         {
           assert(!"global_cur_time modified even though we are inev.");
           abort();
@@ -671,8 +662,8 @@
       while (1)
         {
           cur_time = global_cur_time;
-          if (cur_time == INEVITABLE)
-            {
+          if (cur_time & 1)
+            {                    // there is another inevitable transaction
               CancelLocks(d);
               inev_mutex_acquire();   // wait until released
               inev_mutex_release();
@@ -710,6 +701,22 @@
   update_reads_size_limit(d);
 }
 
+static revision_t acquire_inev_mutex_and_mark_global_cur_time(void)
+{
+  revision_t cur_time;
+
+  inev_mutex_acquire();
+  while (1)
+    {
+      cur_time = global_cur_time;
+      assert((cur_time & 1) == 0);
+      if (bool_cas(&global_cur_time, cur_time, cur_time + 1))
+        break;
+      /* else try again */
+    }
+  return cur_time;
+}
+
 void BecomeInevitable(const char *why)
 {
   revision_t cur_time;
@@ -727,18 +734,13 @@
     }
 #endif
 
-  inev_mutex_acquire();
-  cur_time = global_cur_time;
-  while (!bool_cas(&global_cur_time, cur_time, INEVITABLE))
-    cur_time = global_cur_time;     /* try again */
-  assert(cur_time != INEVITABLE);
-
+  cur_time = acquire_inev_mutex_and_mark_global_cur_time();
   if (d->start_time != cur_time)
     {
       d->start_time = cur_time;
       if (!ValidateDuringTransaction(d, 0))
         {
-          global_cur_time = cur_time;   // must restore the old value
+          global_cur_time = cur_time;   // revert from (cur_time + 1)
           inev_mutex_release();
           AbortTransaction(3);
         }
@@ -756,11 +758,7 @@
   revision_t cur_time;
 
   init_transaction(d);
-  inev_mutex_acquire();
-  cur_time = global_cur_time;
-  while (!bool_cas(&global_cur_time, cur_time, INEVITABLE))
-    cur_time = global_cur_time;     /* try again */
-  assert(cur_time != INEVITABLE);
+  cur_time = acquire_inev_mutex_and_mark_global_cur_time();
   d->start_time = cur_time;
   make_inevitable(d);
 }
@@ -888,7 +886,7 @@
           if (bool_cas(&next_locked_value, d->my_lock, d->my_lock + 2))
             break;
         }
-      if (d->my_lock < LOCKED || d->my_lock == INEVITABLE)
+      if (d->my_lock < LOCKED || d->my_lock == (revision_t)-1)
         {
           /* XXX fix this limitation */
           fprintf(stderr, "XXX error: too many threads ever created "
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to