[pypy-commit] pypy stm-gc: Ensure NEXT is cleared by C code after all.

arigo noreply at buildbot.pypy.org
Sun Apr 22 23:00:00 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54629:c343346db868
Date: 2012-04-22 20:37 +0200
http://bitbucket.org/pypy/pypy/changeset/c343346db868/

Log:	Ensure NEXT is cleared by C code after all. Adapt two more tests.

diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -4,6 +4,7 @@
 from pypy.rpython.annlowlevel import base_ptr_lltype, cast_base_ptr_to_instance
 from pypy.rlib.objectmodel import keepalive_until_here, we_are_translated
 from pypy.rlib.debug import ll_assert
+from pypy.rlib.nonconst import NonConstant
 from pypy.translator.stm.stmgcintf import StmOperations
 
 
@@ -171,7 +172,15 @@
     # This logic is in a sub-function because we want to catch
     # the MemoryErrors that could occur.
     transaction = _cast_voidp_to_transaction(transactionptr)
-    transaction._next_transaction = None
+    #
+    # Sanity-check that C code cleared '_next_transaction' first.
+    # Also needs a bit of nonsensical code to make sure that
+    # '_next_transaction' is always created as a general field.
+    ll_assert(transaction._next_transaction is None,
+              "transaction._next_transaction should be cleared by the C code")
+    if NonConstant(False):
+        transaction._next_transaction = transaction
+    #
     transaction.retry_counter = retry_counter
     new_transactions = transaction.run()
     return _link_new_transactions(new_transactions)
diff --git a/pypy/rlib/test/test_rstm.py b/pypy/rlib/test/test_rstm.py
--- a/pypy/rlib/test/test_rstm.py
+++ b/pypy/rlib/test/test_rstm.py
@@ -21,6 +21,8 @@
         self._add(initial_transaction_ptr)
         while self._pending:
             r, transactionptr = self._pending.popitem()
+            transaction = self.cast_voidp_to_transaction(transactionptr)
+            transaction._next_transaction = None
             nextptr = rstm._stm_run_transaction(transactionptr, 0)
             next = self.cast_voidp_to_transaction(nextptr)
             while next is not None:
diff --git a/pypy/translator/stm/src_stm/fifo.c b/pypy/translator/stm/src_stm/fifo.c
--- a/pypy/translator/stm/src_stm/fifo.c
+++ b/pypy/translator/stm/src_stm/fifo.c
@@ -40,17 +40,14 @@
   return (fifo->first == NULL);
 }
 
-/* static bool_t fifo_is_of_length_1(stm_fifo_t *fifo) */
-/* { */
-/*   return (fifo->first != NULL && fifo->first == fifo->last); */
-/* } */
-
 static void *fifo_popleft(stm_fifo_t *fifo)
 {
   void *item = fifo->first;
   fifo->first = NEXT(item);
   if (fifo->first == NULL)
     fifo->last = NULL;
+  NEXT(item) = NULL;      /* ensure the NEXT is cleared,
+                             to avoid spurious keepalives */
   return item;
 }
 
diff --git a/pypy/translator/stm/src_stm/rpyintf.c b/pypy/translator/stm/src_stm/rpyintf.c
--- a/pypy/translator/stm/src_stm/rpyintf.c
+++ b/pypy/translator/stm/src_stm/rpyintf.c
@@ -93,7 +93,7 @@
           while (1)
             {
               new_transaction_list = perform_transaction(transaction);
-              
+
               /* for now, always break out of this loop,
                  unless 'new_transaction_list' contains precisely one item */
               if (new_transaction_list == NULL)
diff --git a/pypy/translator/stm/test/test_ztranslated.py b/pypy/translator/stm/test/test_ztranslated.py
--- a/pypy/translator/stm/test/test_ztranslated.py
+++ b/pypy/translator/stm/test/test_ztranslated.py
@@ -1,4 +1,5 @@
 import py
+from pypy.rlib import rstm, rgc
 from pypy.translator.stm.test.support import CompiledSTMTests
 from pypy.translator.stm.test import targetdemo
 
@@ -11,33 +12,19 @@
         assert 'check ok!' in data
 
     def test_bug1(self):
-        from pypy.rlib import rstm, rgc
-        from pypy.module.transaction import threadintf
         #
-        class State:
-            pass
-        state = State()
-        #
-        def _foo(_, retry_counter):
-            rgc.collect(0)
-        def _run_thread():
-            rstm.descriptor_init()
-            rstm.perform_transaction(_foo, X, None)
-            threadintf.release(state.ll_unfinished_lock)
-            rstm.descriptor_done()
+        class InitialTransaction(rstm.Transaction):
+            def run(self):
+                rgc.collect(0)
         #
         class X:
             def __init__(self, count):
                 self.count = count
         def g():
             x = X(1000)
-            rstm.enter_transactional_mode()
-            threadintf.start_new_thread(_run_thread)
-            threadintf.acquire(state.ll_unfinished_lock, True)
-            rstm.leave_transactional_mode()
+            rstm.run_all_transactions(InitialTransaction())
             return x
         def entry_point(argv):
-            state.ll_unfinished_lock = threadintf.allocate_lock()
             x = X(len(argv))
             y = g()
             print '<', x.count, y.count, '>'
@@ -48,7 +35,10 @@
         assert '< 5 1000 >' in data, "got: %r" % (data,)
 
     def test_bug2(self):
-        from pypy.rlib import rstm
+        #
+        class DoNothing(rstm.Transaction):
+            def run(self):
+                pass
         #
         class X2:
             pass
@@ -58,8 +48,8 @@
             x = prebuilt2[count]
             x.foobar = 2                    # 'x' becomes a local
             #
-            rstm.enter_transactional_mode() # 'x' becomes the global again
-            rstm.leave_transactional_mode()
+            rstm.run_all_transactions(DoNothing())
+                                            # 'x' becomes the global again
             #
             y = prebuilt2[count]            # same prebuilt obj
             y.foobar += 10                  # 'y' becomes a local


More information about the pypy-commit mailing list