Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit