Author: Remi Meier
Branch: c7-weakref
Changeset: r988:e21afc419f0a
Date: 2014-03-12 17:55 +0100
http://bitbucket.org/pypy/stmgc/changeset/e21afc419f0a/
Log: fix some multi-threading issues
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -54,11 +54,6 @@
after the object. */
GCFLAG_HAS_SHADOW = 0x04,
- /* This flag is set on weakref objects. Weakref objects have a
- reference to the referenced object at the byte-offset
- stmcb_size_rounded_up(obj) - sizeof(void*) */
- GCFLAG_WEAKREF = 0x08,
-
/* All remaining bits of the 32-bit 'stm_flags' field are taken by
the "overflow number". This is a number that identifies the
"overflow objects" from the current transaction among all old
@@ -66,7 +61,7 @@
current transaction that have been flushed out of the nursery,
which occurs if the same transaction allocates too many objects.
*/
- GCFLAG_OVERFLOW_NUMBER_bit0 = 0x10 /* must be last */
+ GCFLAG_OVERFLOW_NUMBER_bit0 = 0x8 /* must be last */
};
diff --git a/c7/stm/weakref.c b/c7/stm/weakref.c
--- a/c7/stm/weakref.c
+++ b/c7/stm/weakref.c
@@ -7,7 +7,9 @@
{
OPT_ASSERT(size_rounded_up > sizeof(struct object_s));
object_t *obj = stm_allocate(size_rounded_up);
- obj->stm_flags |= GCFLAG_WEAKREF;
+
+ assert(_is_in_nursery(obj)); /* see assert(0) which depends on it */
+
LIST_APPEND(STM_PSEGMENT->young_weakrefs, obj);
return obj;
}
@@ -38,13 +40,16 @@
item = pforwarded_array[1]; /* moved location */
}
else {
- /* young outside nursery object */
- if (tree_contains(STM_PSEGMENT->young_outside_nursery,
- (uintptr_t)item)) {
- /* still in the tree -> wasn't seen by the minor
collection,
- so it doesn't survive */
- continue;
- }
+ /* tell me if we need this (requires synchronizing in case
+ of private pages) */
+ assert(0);
+ /* /\* young outside nursery object *\/ */
+ /* if (tree_contains(STM_PSEGMENT->young_outside_nursery, */
+ /* (uintptr_t)item)) { */
+ /* /\* still in the tree -> wasn't seen by the minor
collection, */
+ /* so it doesn't survive *\/ */
+ /* continue; */
+ /* } */
}
assert(!_is_young(item));
@@ -109,7 +114,11 @@
object_t *pointing_to = *WEAKREF_PTR(weakref, size);
assert(pointing_to != NULL);
if (!mark_visited_test(pointing_to)) {
+ //assert(flag_page_private[(uintptr_t)weakref / 4096UL] !=
PRIVATE_PAGE);
*WEAKREF_PTR(weakref, size) = NULL;
+ if (flag_page_private[(uintptr_t)weakref / 4096UL] ==
PRIVATE_PAGE) {
+ synchronize_overflow_object_now(weakref);
+ }
/* we don't need it in this list anymore */
list_set_item(lst, n, list_pop_item(lst));
diff --git a/c7/test/test_weakref.py b/c7/test/test_weakref.py
--- a/c7/test/test_weakref.py
+++ b/c7/test/test_weakref.py
@@ -113,6 +113,37 @@
self.abort_transaction()
+ def test_multiple_threads(self):
+ self.start_transaction()
+ lp0 = stm_allocate(1024)
+ self.push_root(lp0)
+ self.commit_transaction()
+
+ self.start_transaction()
+ lp0 = self.pop_root()
+ self.push_root(lp0)
+ stm_write(lp0) # privatize page
+
+ self.push_root_no_gc()
+ lp2 = stm_allocate(48)
+ lp1 = stm_allocate_weakref(lp2) # no collection here
+ self.pop_root()
+
+ self.push_root(lp0)
+ self.push_root(lp1)
+ self.commit_transaction()
+ # lp2 dies
+ lp1 = self.pop_root()
+ self.push_root(lp1)
+
+ assert stm_get_weakref(lp1) == ffi.NULL
+
+ self.switch(1)
+
+ assert stm_get_weakref(lp1) == ffi.NULL
+
+
+
class TestMajorCollection(BaseTest):
def test_simple(self):
@@ -188,3 +219,35 @@
lp1 = self.pop_root()
# lp2 died
assert stm_get_weakref(lp1) == ffi.NULL
+
+ def test_multiple_threads(self):
+ self.start_transaction()
+ lp0 = stm_allocate(48)
+ lp1 = stm_allocate_weakref(lp0) # no collection here
+ self.push_root(lp1)
+ self.push_root(lp0)
+ self.commit_transaction()
+
+ self.start_transaction()
+ lp0 = self.pop_root()
+ lp1 = self.pop_root()
+ self.push_root(lp1)
+
+ stm_write(lp0) # privatize page with weakref in it too
+
+ assert stm_get_page_flag(stm_get_obj_pages(lp1)[0]) == PRIVATE_PAGE
+ assert stm_get_weakref(lp1) == lp0
+
+ self.commit_transaction()
+ self.start_transaction()
+
+ # lp0 dies
+ stm_major_collect()
+
+ assert stm_get_weakref(lp1) == ffi.NULL
+ print stm_get_real_address(lp1)
+
+ self.switch(1)
+
+ assert stm_get_weakref(lp1) == ffi.NULL
+ print stm_get_real_address(lp1)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit