Author: Armin Rigo <ar...@tunes.org>
Branch: nogil-unsafe-2
Changeset: r90420:56c4cf2a149a
Date: 2017-02-28 13:53 +0100
http://bitbucket.org/pypy/pypy/changeset/56c4cf2a149a/

Log:    (fijal, arigo) test and fix

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -1653,12 +1653,25 @@
     # ----------
     # Nursery collection
 
+    def zero_nursery_pointers_in_all_threads(self):
+        pass    # patched in test_thread
+
     def _minor_collection(self):
         """Perform a minor collection: find the objects from the nursery
         that remain alive and move them out."""
         #
         debug_start("gc-minor")
         #
+        # First, write NULLs in all thread's nursery_free and
+        # nursery_top
+        if we_are_translated():
+            def zero_nursery_pointers(arg, tl):
+                (tl + NURSERY_FREE.offset).address[0] = llmemory.NULL
+                (tl + NURSERY_TOP.offset).address[0] = llmemory.NULL
+            rthread.enum_all_threadlocals(zero_nursery_pointers, None)
+        else:
+            self.zero_nursery_pointers_in_all_threads()
+        #
         # All nursery barriers are invalid from this point on.  They
         # are evaluated anew as part of the minor collection.
         self.nursery_barriers.delete()
diff --git a/rpython/memory/gc/test/test_thread.py 
b/rpython/memory/gc/test/test_thread.py
--- a/rpython/memory/gc/test/test_thread.py
+++ b/rpython/memory/gc/test/test_thread.py
@@ -1,5 +1,5 @@
 import pytest
-from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.memory.gc import incminimark
 from rpython.memory.gc.test.test_direct import BaseDirectGCTest, S
 
@@ -14,9 +14,15 @@
                         incminimark.NEXT_NUBLOCK,
                         ]
 
-    def __init__(self):
+    def __init__(self, gc):
         self.cache = {}
         self.switch_thread(0)
+        gc.zero_nursery_pointers_in_all_threads = self._zero_pointers
+
+    def _zero_pointers(self):
+        for (tl, thread_num), local in self.cache.items():
+            if tl in (incminimark.NURSERY_FREE, incminimark.NURSERY_TOP):
+                local.rawvalue = llmemory.NULL
 
     def switch_thread(self, thread_num):
         for tl in self.all_threadlocals:
@@ -27,11 +33,19 @@
     from rpython.memory.gc.incminimark import IncrementalMiniMarkGC as GCClass
 
     def test_malloc_fixedsize(self):
-        ts = ThreadSwitcher()
+        ts = ThreadSwitcher(self.gc)
         for i in range(1000):
             p = self.malloc(S)
             p.x = 42
             assert p.prev == lltype.nullptr(S)
             assert p.next == lltype.nullptr(S)
             ts.switch_thread(i & 1)
-        #...
+
+    def test_malloc_fixedsize_2(self):
+        ts = ThreadSwitcher(self.gc)
+        for i in range(1000):
+            p = self.malloc(S)
+            p.x = 42
+            assert p.prev == lltype.nullptr(S)
+            assert p.next == lltype.nullptr(S)
+            ts.switch_thread(0 if i % 5 < 2 else 1)
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -469,3 +469,15 @@
 
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
+
+
+@specialize.arg(0)
+def enum_all_threadlocals(callback, arg):
+    p = llmemory.NULL
+    llop.threadlocalref_acquire(lltype.Void)
+    while True:
+        p = llop.threadlocalref_enum(llmemory.Address, p)
+        if not p:
+            break
+        callback(arg, p)
+    llop.threadlocalref_release(lltype.Void)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to