[pypy-commit] stmgc default: more asserts and fix the case when start_exclusivelock() returns in a
Raemi
noreply at buildbot.pypy.org
Thu Nov 21 10:57:41 CET 2013
Author: Remi Meier <remi.meier at gmail.com>
Branch:
Changeset: r550:c0bc566a9af3
Date: 2013-11-21 10:57 +0100
http://bitbucket.org/pypy/stmgc/changeset/c0bc566a9af3/
Log: more asserts and fix the case when start_exclusivelock() returns in
a transaction that needs to abort (same as after
stm_start_sharedlock())
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1745,6 +1745,8 @@
/* there may be a thread holding the collection lock
because it steals a stub belonging to the thread
that previously owned this descriptor.
+ (not currently, as we do a start_exclusivelock()
+ before calling DescriptorInit)
*/
}
else {
@@ -1809,6 +1811,10 @@
gcptrlist_delete(&d->public_descriptor->stolen_objects);
gcptrlist_delete(&d->public_descriptor->stolen_young_stubs);
+ assert(d->young_weakrefs.size == 0);
+ assert(d->public_with_young_copy.size == 0);
+ assert(d->old_objects_to_trace.size == 0);
+
stmgcpage_done_tls();
i = d->public_descriptor_index;
assert(stm_descriptor_array[i] == d->public_descriptor);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -278,6 +278,9 @@
static void trace_stub(struct tx_descriptor *d, gcptr S)
{
+ /* ignore stub if it is outdated, because then the transaction
+ will abort (or has been aborted long ago) */
+
revision_t w = ACCESS_ONCE(S->h_revision);
if ((w & 3) != 2) {
/* P has a ptr in h_revision, but this object is not a stub
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -256,8 +256,11 @@
memset(&sd.all_stubs, 0, sizeof(sd.all_stubs));
steal_data = &sd;
stmgc_trace(L, &replace_ptr_to_protected_with_stub);
- if (L->h_tid & GCFLAG_WEAKREF)
+ if (L->h_tid & GCFLAG_WEAKREF) {
+ /* We have to trace the weakref manually because stmgc_trace
+ doesn't */
replace_ptr_to_protected_with_stub(WEAKREF_PTR(L, stmgc_size(L)));
+ }
g2l_delete_not_used_any_more(&sd.all_stubs);
/* If another thread (the foreign or a 3rd party) does a read
diff --git a/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -88,6 +88,7 @@
XXX: remove again when sure it is not needed
(interaction with stop_all_other_threads()) */
start_exclusivelock();
+ assert(stm_active == 0);
stmgcpage_acquire_global_lock();
#ifdef STM_BARRIER_COUNT
static int seen = 0;
@@ -116,6 +117,7 @@
if (token == 1) {
start_exclusivelock();
+ assert(stm_active == 0);
stmgcpage_acquire_global_lock();
done_shadowstack();
stmgc_done_nursery();
@@ -384,6 +386,14 @@
ACCESS_ONCE(sync_required) = -1;
stm_stop_sharedlock();
start_exclusivelock();
+ if (stm_active < 0) {
+ /* we have to give up and abort. Another thread did
+ a major collect and makes us abort now */
+ stop_exclusivelock();
+ stm_start_sharedlock();
+ assert(stm_active < 0);
+ AbortNowIfDelayed();
+ }
ACCESS_ONCE(sync_required) = 0;
assert(in_single_thread == NULL);
@@ -400,6 +410,10 @@
stop_exclusivelock();
stm_start_sharedlock();
+
+ /* another thread may commit, start a major collect, and
+ make us abort */
+ AbortNowIfDelayed();
}
void stm_possible_safe_point(void)
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -39,10 +39,13 @@
if (stmgc_is_in_nursery(d, pointing_to)) {
if (pointing_to->h_tid & GCFLAG_MOVED) {
+ gcptr to = (gcptr)pointing_to->h_revision;
dprintf(("weakref ptr moved %p->%p\n",
- *WEAKREF_PTR(weakref, size),
- (gcptr)pointing_to->h_revision));
- *WEAKREF_PTR(weakref, size) = (gcptr)pointing_to->h_revision;
+ *WEAKREF_PTR(weakref, size), to));
+ *WEAKREF_PTR(weakref, size) = to;
+ assert(to->h_tid & GCFLAG_OLD);
+ assert(!(to->h_tid & GCFLAG_MOVED));
+ assert(!(pointing_to->h_tid & GCFLAG_OLD));
}
else {
assert(!IS_POINTER(pointing_to->h_revision));
More information about the pypy-commit
mailing list