Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r1640:78281a990907
Date: 2015-02-21 12:49 +0100
http://bitbucket.org/pypy/stmgc/changeset/78281a990907/

Log:    Fix

diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -134,14 +134,19 @@
 
     char *p = allocate_outside_nursery_large(size_rounded_up);
     uintptr_t nobj = p - stm_object_pages;
+    dprintf(("allocate_preexisting: %p\n", (object_t *)nobj));
     long j;
     for (j = 0; j <= NB_SEGMENTS; j++) {
         char *dest = get_segment_base(j) + nobj;
         memcpy(dest, initial_data, size_rounded_up);
         ((struct object_s *)dest)->stm_flags = GCFLAG_WRITE_BARRIER;
-        if (j) {
+#ifdef STM_TESTS
+        /* can't really enable this check outside tests, because there is
+           a change that the transaction_state changes in parallel */
+        if (j && get_priv_segment(j)->transaction_state != TS_NONE) {
             assert(!was_read_remote(get_segment_base(j), (object_t *)nobj));
         }
+#endif
     }
 
     release_privatization_lock();
diff --git a/c7/stm/hashtable.c b/c7/stm/hashtable.c
--- a/c7/stm/hashtable.c
+++ b/c7/stm/hashtable.c
@@ -107,8 +107,12 @@
 
 static bool _stm_was_read_by_anybody(object_t *obj)
 {
+    /* can only be safely called during major GC, when all other threads
+       are suspended */
     long i;
     for (i = 1; i <= NB_SEGMENTS; i++) {
+        if (get_priv_segment(i)->transaction_state == TS_NONE)
+            continue;
         if (was_read_remote(get_segment_base(i), obj))
             return true;
     }
diff --git a/c7/test/test_hashtable.py b/c7/test/test_hashtable.py
--- a/c7/test/test_hashtable.py
+++ b/c7/test/test_hashtable.py
@@ -105,10 +105,12 @@
         self.start_transaction()
         h = self.pop_root()
         stm_set_char(lp2, 'B')
+        self.switch(1)
+        self.start_transaction()
+        self.switch(0)
         htset(h, 9991234, lp2, tl0)
         #
         self.switch(1)
-        self.start_transaction()
         lp1b = htget(h, 1234)
         assert lp1b != ffi.NULL
         assert stm_get_char(lp1b) == 'A'
@@ -303,6 +305,36 @@
         self.switch(0)
         stm_major_collect()       # to get rid of the hashtable object
 
+    def test_grow_without_conflict(self):
+        self.start_transaction()
+        h = self.allocate_hashtable()
+        self.push_root(h)
+        self.commit_transaction()
+        h = self.pop_root()
+        self.push_root(h)
+        #
+        STEPS = 50
+        for i in range(STEPS):
+            self.switch(1)
+            self.start_transaction()
+            tl0 = self.tls[self.current_thread]
+            htset(h, i + STEPS, stm_allocate(32), tl0)
+            #
+            self.switch(0)
+            self.start_transaction()
+            tl0 = self.tls[self.current_thread]
+            htset(h, i, stm_allocate(24), tl0)
+            #
+            self.switch(1)
+            self.commit_transaction()
+            #
+            self.switch(0)
+            self.commit_transaction()
+        #
+        self.pop_root()
+        self.start_transaction()
+        stm_major_collect()       # to get rid of the hashtable object
+
 
 class TestRandomHashtable(BaseTestHashtable):
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to