[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