[pypy-commit] pypy stm-gc: Copy the logic for thread-locals. The last new test is the one failing

arigo noreply at buildbot.pypy.org
Sun Apr 29 10:53:39 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54800:4c6a625119f9
Date: 2012-04-29 10:33 +0200
http://bitbucket.org/pypy/pypy/changeset/4c6a625119f9/

Log:	Copy the logic for thread-locals. The last new test is the one
	failing because it needs slightly special care.

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
@@ -238,7 +238,8 @@
         # they are simply added to 'pending'.
         self.collect_roots_from_stack()
         #
-        # Find the roots that are living in raw structures.
+        # Find the roots that are living in raw structures, and in
+        # thread-local raw structures.
         self.collect_from_raw_structures()
         #
         # Also find the roots that are the local copy of GCFLAG_WAS_COPIED
@@ -388,6 +389,8 @@
     def collect_from_raw_structures(self):
         self.gc.root_walker.walk_current_nongc_roots(
             StmGCTLS._trace_drag_out1, self)
+        self.gc.root_walker.walk_current_thrloc_roots(
+            StmGCTLS._trace_drag_out1, self)
 
     def trace_and_drag_out_of_nursery(self, obj):
         # This is called to fix the references inside 'obj', to ensure that
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,6 +135,8 @@
         pass     # no stack roots in this test file
     def walk_current_nongc_roots(self, *args):
         pass     # no nongc roots in this test file
+    def walk_current_thrloc_roots(self, *args):
+        pass     # no thread-local roots in this test file
 
 
 class StmGCTests:
@@ -851,7 +853,7 @@
         a = self.gc.stm_normalize_global(tr1_adr)
         assert a == sr1_adr
 
-    def test_prebuilt_nongc(self):
+    def test_prebuilt_nongc_main(self):
         from pypy.rpython.memory.gc.test import test_stmtls
         self.gc.root_walker = test_stmtls.FakeRootWalker()
         NONGC = lltype.Struct('NONGC', ('s', lltype.Ptr(S)))
@@ -863,4 +865,50 @@
         self.gc.collect(0)                      # keeps LOCAL
         s = nongc.s                             # reload, it moved
         s_adr = llmemory.cast_ptr_to_adr(s)
-        self.checkflags(s_adr, False, False)    # check it survived
+        self.checkflags(s_adr, False, False)    # check it survived; local
+
+    def test_prebuilt_nongc_enterleave(self):
+        from pypy.rpython.memory.gc.test import test_stmtls
+        self.gc.root_walker = test_stmtls.FakeRootWalker()
+        NONGC = lltype.Struct('NONGC', ('s', lltype.Ptr(S)))
+        nongc = lltype.malloc(NONGC, immortal=True, flavor='raw')
+        self.gc.root_walker.prebuilt_nongc = [(nongc, 's')]
+        #
+        s, _ = self.malloc(S, globl=False)      # a local object
+        nongc.s = s
+        self.gc.enter_transactional_mode()      # forces it to become GLOBAL
+        self.gc.leave_transactional_mode()
+        s = nongc.s                             # reload, it moved
+        s_adr = llmemory.cast_ptr_to_adr(s)
+        self.checkflags(s_adr, True, False)     # check it survived; global
+
+    def test_prebuilt_threadlocal_main(self):
+        from pypy.rpython.memory.gc.test import test_stmtls
+        self.gc.root_walker = test_stmtls.FakeRootWalker()
+        THREADLOCAL = lltype.Struct('THREADLOCAL', ('s', lltype.Ptr(S)),
+                                    hints={'stm_thread_local': True})
+        threadlocal = lltype.malloc(THREADLOCAL, immortal=True, flavor='raw')
+        self.gc.root_walker.prebuilt_threadlocal = [(threadlocal, 's')]
+        #
+        s, _ = self.malloc(S, globl=False)      # a local object
+        threadlocal.s = s
+        self.gc.collect(0)                      # keeps LOCAL
+        s = threadlocal.s                       # reload, it moved
+        s_adr = llmemory.cast_ptr_to_adr(s)
+        self.checkflags(s_adr, False, False)    # check it survived; local
+
+    def test_prebuilt_threadlocal_enterleave(self):
+        from pypy.rpython.memory.gc.test import test_stmtls
+        self.gc.root_walker = test_stmtls.FakeRootWalker()
+        THREADLOCAL = lltype.Struct('THREADLOCAL', ('s', lltype.Ptr(S)),
+                                    hints={'stm_thread_local': True})
+        threadlocal = lltype.malloc(THREADLOCAL, immortal=True, flavor='raw')
+        self.gc.root_walker.prebuilt_threadlocal = [(threadlocal, 's')]
+        #
+        s, _ = self.malloc(S, globl=False)     # a local object
+        threadlocal.s = s
+        self.gc.enter_transactional_mode()     # 's' remains LOCAL (difference)
+        self.gc.leave_transactional_mode()
+        s = threadlocal.s                      # reload, it moved
+        s_adr = llmemory.cast_ptr_to_adr(s)
+        self.checkflags(s_adr, False, False)   # check it survived; still local
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
@@ -27,6 +27,7 @@
 class FakeRootWalker:
     current_stack = ()
     prebuilt_nongc = ()
+    prebuilt_threadlocal = ()
 
     def collect_list(self, lst):
         A = lltype.Array(llmemory.Address)
@@ -56,6 +57,10 @@
         for root in self.collect_field_list(self.prebuilt_nongc):
             callback(arg, root)
 
+    def walk_current_thrloc_roots(self, callback, arg):
+        for root in self.collect_field_list(self.prebuilt_threadlocal):
+            callback(arg, root)
+
 class FakeGC:
     from pypy.rpython.memory.support import AddressDict, null_address_dict
     AddressStack = get_address_stack()


More information about the pypy-commit mailing list