[pypy-commit] pypy stm: (antocuni, arigo)

arigo noreply at buildbot.pypy.org
Tue Jan 17 14:52:50 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r51398:29e9345db0e6
Date: 2012-01-17 11:57 +0100
http://bitbucket.org/pypy/pypy/changeset/29e9345db0e6/

Log:	(antocuni, arigo) Test and fix: handle the case of
	stm_{get,set}field() called after descriptor_init() but outside a
	transaction.

diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -80,15 +80,19 @@
 #endif
   unsigned int spinloop_counter;
   owner_version_t my_lock_word;
-  unsigned init_counter;
   struct RedoLog redolog;   /* last item, because it's the biggest one */
   int transaction_active;
 };
 
+static const struct tx_descriptor null_tx = {
+  .transaction_active = 0
+};
+#define NULL_TX  ((struct tx_descriptor *)(&null_tx))
+
 /* global_timestamp contains in its lowest bit a flag equal to 1
    if there is an inevitable transaction running */
 static volatile unsigned long global_timestamp = 2;
-static __thread struct tx_descriptor *thread_descriptor = NULL;
+static __thread struct tx_descriptor *thread_descriptor = NULL_TX;
 #ifdef COMMIT_OTHER_INEV
 static struct tx_descriptor *volatile thread_descriptor_inev;
 static volatile unsigned long d_inev_checking = 0;
@@ -509,11 +513,8 @@
 long stm_read_word(long* addr)
 {
   struct tx_descriptor *d = thread_descriptor;
-  if (!d)
+  if (!d->transaction_active)
     return *addr;
-#ifdef RPY_STM_ASSERT
-  assert(d->transaction_active);
-#endif
 
   // check writeset first
   wlog_t* found;
@@ -575,23 +576,18 @@
 void stm_write_word(long* addr, long val)
 {
   struct tx_descriptor *d = thread_descriptor;
-  if (!d)
-    {
-      *addr = val;
-      return;
-    }
-#ifdef RPY_STM_ASSERT
-  assert(d->transaction_active);
-#endif
+  if (!d->transaction_active) {
+    *addr = val;
+    return;
+  }
   redolog_insert(&d->redolog, addr, val);
 }
 
 
 void stm_descriptor_init(void)
 {
-  if (thread_descriptor != NULL)
-    thread_descriptor->init_counter++;
-  else
+  assert(thread_descriptor == NULL_TX);
+  if (1)  /* for hg diff */
     {
       struct tx_descriptor *d = malloc(sizeof(struct tx_descriptor));
       memset(d, 0, sizeof(struct tx_descriptor));
@@ -606,7 +602,6 @@
         d->my_lock_word = ~d->my_lock_word;
       assert(IS_LOCKED(d->my_lock_word));
       d->spinloop_counter = (unsigned int)(d->my_lock_word | 1);
-      d->init_counter = 1;
 
       thread_descriptor = d;
 
@@ -621,11 +616,9 @@
 void stm_descriptor_done(void)
 {
   struct tx_descriptor *d = thread_descriptor;
-  d->init_counter--;
-  if (d->init_counter > 0)
-    return;
+  assert(d != NULL_TX);
 
-  thread_descriptor = NULL;
+  thread_descriptor = NULL_TX;
 
 #ifdef RPY_STM_DEBUG_PRINT
   PYPY_DEBUG_START("stm-done");
@@ -671,7 +664,7 @@
 {
   void *result;
   /* you need to call descriptor_init() before calling stm_perform_transaction */
-  assert(thread_descriptor != NULL);
+  assert(thread_descriptor != NULL_TX);
   STM_begin_transaction();
   result = callback(arg);
   stm_commit_transaction();
@@ -767,7 +760,7 @@
      by another thread.  We set the lowest bit in global_timestamp
      to 1. */
   struct tx_descriptor *d = thread_descriptor;
-  if (!d)
+  if (!d->transaction_active)
     return;
 
 #ifdef RPY_STM_ASSERT
@@ -965,7 +958,7 @@
 long stm_debug_get_state(void)
 {
   struct tx_descriptor *d = thread_descriptor;
-  if (!d)
+  if (d == NULL_TX)
     return -1;
   if (!d->transaction_active)
     return 0;
diff --git a/pypy/translator/stm/test/test_funcgen.py b/pypy/translator/stm/test/test_funcgen.py
--- a/pypy/translator/stm/test/test_funcgen.py
+++ b/pypy/translator/stm/test/test_funcgen.py
@@ -257,6 +257,16 @@
         t, cbuilder = self.compile(do_stm_getfield)
         cbuilder.cmdexec('')
 
+    def test_getfield_all_sizes_outside_transaction(self):
+        def do_stm_getfield(argv):
+            stm_descriptor_init()
+            # we have a descriptor, but we don't call it in a transaction
+            _play_with_getfield(None)
+            stm_descriptor_done()
+            return 0
+        t, cbuilder = self.compile(do_stm_getfield)
+        cbuilder.cmdexec('')
+
     def test_setfield_all_sizes(self):
         def do_stm_setfield(argv):
             _play_with_setfields(None)
@@ -277,6 +287,15 @@
         t, cbuilder = self.compile(do_stm_setfield)
         cbuilder.cmdexec('')
 
+    def test_setfield_all_sizes_outside_transaction(self):
+        def do_stm_setfield(argv):
+            stm_descriptor_init()
+            _play_with_setfields(None)
+            stm_descriptor_done()
+            return 0
+        t, cbuilder = self.compile(do_stm_setfield)
+        cbuilder.cmdexec('')
+
     def test_getarrayitem_all_sizes(self):
         def do_stm_getarrayitem(argv):
             _play_with_getarrayitem(None)


More information about the pypy-commit mailing list