[pypy-commit] pypy stm-gc: We really need to know if we're starting a new or restarting an aborted

arigo noreply at buildbot.pypy.org
Tue Apr 17 11:59:14 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54457:93da8b4ece49
Date: 2012-04-17 11:58 +0200
http://bitbucket.org/pypy/pypy/changeset/93da8b4ece49/

Log:	We really need to know if we're starting a new or restarting an
	aborted transaction.

diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -14,7 +14,7 @@
 @specialize.memo()
 def _get_stm_callback(func, argcls):
     def _stm_callback(llarg, retry_counter):
-        llop.stm_start_transaction(lltype.Void)
+        llop.stm_start_transaction(lltype.Void, retry_counter)
         if we_are_translated():
             llarg = rffi.cast(rclass.OBJECTPTR, llarg)
             arg = cast_base_ptr_to_instance(argcls, llarg)
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -632,7 +632,7 @@
     from pypy.translator.stm import stmgcintf
     stmgcintf.StmOperations.del_tls()
 
-def op_stm_start_transaction():
+def op_stm_start_transaction(retry_counter):
     pass
 
 def op_stm_commit_transaction():
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -121,7 +121,7 @@
         #
         from pypy.rpython.memory.gc.stmtls import StmGCTLS
         self.main_thread_tls = StmGCTLS(self, in_main_thread=True)
-        self.main_thread_tls.start_transaction()
+        self.main_thread_tls.start_transaction(-1)
 
     def setup_thread(self):
         from pypy.rpython.memory.gc.stmtls import StmGCTLS
@@ -195,8 +195,8 @@
         if gen > 0:
             debug_print("XXX not doing a global collect()")
 
-    def start_transaction(self):
-        self.get_tls().start_transaction()
+    def start_transaction(self, retry_counter):
+        self.get_tls().start_transaction(retry_counter)
 
     def commit_transaction(self):
         self.get_tls().stop_transaction()
diff --git a/pypy/rpython/memory/gc/stmtls.py b/pypy/rpython/memory/gc/stmtls.py
--- a/pypy/rpython/memory/gc/stmtls.py
+++ b/pypy/rpython/memory/gc/stmtls.py
@@ -117,19 +117,24 @@
                 if value is not self:
                     del StmGCTLS.nontranslated_dict[key]
         self.stm_operations.leave_transactional_mode()
-        self.start_transaction()
+        self.start_transaction(-1)
 
-    def start_transaction(self):
+    def start_transaction(self, retry_counter):
         """Start a transaction: performs any pending cleanups, and set
         up a fresh state for allocating.  Called at the start of
         each transaction, and at the start of the main thread."""
         # Note that the calls to enter() and
         # end_of_transaction_collection() are not balanced: if a
-        # transaction is aborted, the latter might never be called.
+        # transaction is aborted, the latter might never be called
+        # and we get back to here with retry_counter > 0.
         # Be ready here to clean up any state.
         self._cleanup_state()
-        if self is not self.gc.main_thread_tls:
-            self.gc.root_walker.clear_current_stack_roots()
+        rw = self.gc.root_walker
+        if retry_counter > 0:
+            rw.set_current_stack_roots_limit(self.stack_root_limit)
+        else:
+            self.stack_root_limit = rw.get_current_stack_roots_limit()
+        #
         if self.nursery_free:
             clear_size = self.nursery_free - self.nursery_start
         else:
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -135,8 +135,8 @@
 class FakeRootWalker:
     def walk_current_stack_roots(self, *args):
         pass     # no stack roots in this test file
-    def clear_current_stack_roots(self):
-        pass
+    def get_current_stack_roots_limit(self):
+        return "some limit"
 
 
 class StmGCTests:
@@ -189,7 +189,7 @@
         self.gc.stm_operations.threadnum = threadnum
         if threadnum not in self.gc.stm_operations._tls_dict:
             self.gc.setup_thread()
-            self.gc.start_transaction()
+            self.gc.start_transaction(0)
     def gcsize(self, S):
         return (llmemory.raw_malloc_usage(llmemory.sizeof(self.gc.HDR)) +
                 llmemory.raw_malloc_usage(llmemory.sizeof(S)))
diff --git a/pypy/rpython/memory/gc/test/test_stmtls.py b/pypy/rpython/memory/gc/test/test_stmtls.py
--- a/pypy/rpython/memory/gc/test/test_stmtls.py
+++ b/pypy/rpython/memory/gc/test/test_stmtls.py
@@ -38,6 +38,8 @@
             P = lltype.typeOf(self.current_stack[i])
             self.current_stack[i] = llmemory.cast_adr_to_ptr(roots[i], P)
         lltype.free(roots, flavor='raw')
+    def get_current_stack_roots_limit(self):
+        return "some limit"
 
 class FakeGC:
     from pypy.rpython.memory.support import AddressDict, null_address_dict
@@ -83,7 +85,7 @@
         self.gctls_main = StmGCTLS(self.gc, in_main_thread=True)
         self.gctls_thrd = StmGCTLS(self.gc, in_main_thread=False)
         self.gc.main_thread_tls = self.gctls_main
-        self.gctls_main.start_transaction()
+        self.gctls_main.start_transaction(-1)
         self.gc.root_walker.current_stack = self.current_stack
 
     def stack_add(self, p):
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
--- a/pypy/rpython/memory/gctransform/stmframework.py
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -42,7 +42,7 @@
             [s_gc], annmodel.s_None)
         self.stm_start_ptr = getfn(
             self.gcdata.gc.start_transaction.im_func,
-            [s_gc], annmodel.s_None)
+            [s_gc, annmodel.SomeInteger()], annmodel.s_None)
         self.stm_commit_ptr = getfn(
             self.gcdata.gc.commit_transaction.im_func,
             [s_gc], annmodel.s_None)
@@ -84,7 +84,9 @@
         hop.genop('cast_adr_to_ptr', [v_globaladr], resultvar=op.result)
 
     def gct_stm_start_transaction(self, hop):
-        hop.genop("direct_call", [self.stm_start_ptr, self.c_const_gc])
+        v_int = hop.spaceop.args[0]
+        hop.genop("direct_call", [self.stm_start_ptr,
+                                  self.c_const_gc, v_int])
 
     def gct_stm_commit_transaction(self, hop):
         hop.genop("direct_call", [self.stm_commit_ptr, self.c_const_gc])
@@ -170,8 +172,10 @@
                            stackgcdata.root_stack_base,
                            stackgcdata.root_stack_top)
 
-    def clear_current_stack_roots(self):
+    def get_current_stack_roots_limit(self):
+        return self.stackgcdata.root_stack_top
+
+    def set_current_stack_roots_limit(self, limit):
         """Used when we start a transaction: there might be garbage left
         behind by the previous aborted transaction."""
-        stackgcdata = self.stackgcdata
-        stackgcdata.root_stack_top = stackgcdata.root_stack_base
+        self.stackgcdata.root_stack_top = limit


More information about the pypy-commit mailing list