[pypy-commit] stmgc c8-gil-like: demo_random.c starts to work

arigo noreply at buildbot.pypy.org
Thu Jun 11 22:32:41 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: c8-gil-like
Changeset: r1806:e2e9d6b116b9
Date: 2015-06-11 17:41 +0200
http://bitbucket.org/pypy/stmgc/changeset/e2e9d6b116b9/

Log:	demo_random.c starts to work

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1287,28 +1287,41 @@
 
 void _stm_commit_transaction(void)
 {
+    assert(STM_PSEGMENT->running_pthread == pthread_self());
+    _core_commit_transaction(/*external=*/ false);
+}
+
+static void _core_commit_transaction(bool external)
+{
     exec_local_finalizers();
 
     assert(!_has_mutex());
     assert(STM_PSEGMENT->safe_point == SP_RUNNING);
-    assert(STM_PSEGMENT->running_pthread == pthread_self());
 
-    dprintf(("> stm_commit_transaction()\n"));
-    minor_collection(1);
+    dprintf(("> stm_commit_transaction(external=%d)\n", (int)external));
+    minor_collection(/*commit=*/ true, external);
 
-    _core_commit_transaction();
-}
-
-static void _core_commit_transaction(void)
-{
     push_large_overflow_objects_to_other_segments();
     /* push before validate. otherwise they are reachable too early */
 
+    if (external) {
+        /* from this point on, unlink the original 'stm_thread_local_t *'
+           from its segment.  Better do it as soon as possible, because
+           other threads might be spin-looping, waiting for the -1 to
+           disappear. */
+        STM_SEGMENT->running_thread = NULL;
+        write_fence();
+        assert(_stm_detached_inevitable_from_thread == -1);
+        _stm_detached_inevitable_from_thread = 0;
+    }
+
     bool was_inev = STM_PSEGMENT->transaction_state == TS_INEVITABLE;
     _validate_and_add_to_commit_log();
 
-    if (!was_inev)
+    if (!was_inev) {
+        assert(!external);
         stm_rewind_jmp_forget(STM_SEGMENT->running_thread);
+    }
 
     /* XXX do we still need a s_mutex_lock() section here? */
     s_mutex_lock();
@@ -1326,12 +1339,14 @@
     invoke_and_clear_user_callbacks(0);   /* for commit */
 
     /* >>>>> there may be a FORK() happening in the safepoint below <<<<<*/
-    enter_safe_point_if_requested();
-    assert(STM_SEGMENT->nursery_end == NURSERY_END);
+    if (!external) {
+        enter_safe_point_if_requested();
+        assert(STM_SEGMENT->nursery_end == NURSERY_END);
 
-    /* if a major collection is required, do it here */
-    if (is_major_collection_requested()) {
-        major_collection_with_mutex();
+        /* if a major collection is required, do it here */
+        if (is_major_collection_requested()) {
+            major_collection_with_mutex();
+        }
     }
 
     _verify_cards_cleared_in_all_lists(get_priv_segment(STM_SEGMENT->segment_num));
@@ -1342,6 +1357,7 @@
 
     /* done */
     stm_thread_local_t *tl = STM_SEGMENT->running_thread;
+    assert(external == (tl == NULL));
     _finish_transaction(STM_TRANSACTION_COMMIT);
     /* cannot access STM_SEGMENT or STM_PSEGMENT from here ! */
 
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -300,7 +300,7 @@
 
 static void _signal_handler(int sig, siginfo_t *siginfo, void *context);
 static bool _stm_validate(void);
-static void _core_commit_transaction(void);
+static void _core_commit_transaction(bool external);
 
 static inline bool was_read_remote(char *base, object_t *obj)
 {
diff --git a/c8/stm/detach.c b/c8/stm/detach.c
--- a/c8/stm/detach.c
+++ b/c8/stm/detach.c
@@ -49,26 +49,8 @@
 
 static void commit_external_inevitable_transaction(void)
 {
-    assert(!_has_mutex());
-    assert(STM_PSEGMENT->safe_point == SP_RUNNING);
     assert(STM_PSEGMENT->transaction_state == TS_INEVITABLE); /* can't abort */
-
-    exec_local_finalizers();
-    minor_collection(1);
-
-    /* from this point on, unlink the original 'stm_thread_local_t *'
-       from its segment.  Better do it as soon as possible, because
-       other threads might be spin-looping, waiting for the -1 to
-       disappear.  XXX could be done even earlier, as soon as we have
-       read the shadowstack inside the minor collection. */
-    STM_SEGMENT->running_thread = NULL;
-
-    _core_commit_transaction();
-
-
-    write_fence();
-    assert(_stm_detached_inevitable_from_thread == -1);
-    _stm_detached_inevitable_from_thread = 0;
+    _core_commit_transaction(/*external=*/ true);
 }
 
 void _stm_reattach_transaction(intptr_t old, stm_thread_local_t *tl)
@@ -92,6 +74,7 @@
         dprintf(("reattach_transaction: commit detached from seg %d\n",
                  remote_seg_num));
 
+        tl->last_associated_segment_num = remote_seg_num;
         ensure_gs_register(remote_seg_num);
         commit_external_inevitable_transaction();
     }
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -564,11 +564,12 @@
     assert(MINOR_NOTHING_TO_DO(STM_PSEGMENT));
 }
 
-static void minor_collection(bool commit)
+static void minor_collection(bool commit, bool external)
 {
     assert(!_has_mutex());
 
-    stm_safe_point();
+    if (!external)
+        stm_safe_point();
 
     timing_event(STM_SEGMENT->running_thread, STM_GC_MINOR_START);
 
@@ -582,7 +583,7 @@
     if (level > 0)
         force_major_collection_request();
 
-    minor_collection(/*commit=*/ false);
+    minor_collection(/*commit=*/ false, /*external=*/ false);
 
 #ifdef STM_TESTS
     /* tests don't want aborts in stm_allocate, thus
diff --git a/c8/stm/nursery.h b/c8/stm/nursery.h
--- a/c8/stm/nursery.h
+++ b/c8/stm/nursery.h
@@ -10,7 +10,7 @@
                                 object_t *obj, uint8_t mark_value,
                                 bool mark_all, bool really_clear);
 
-static void minor_collection(bool commit);
+static void minor_collection(bool commit, bool external);
 static void check_nursery_at_transaction_start(void);
 static size_t throw_away_nursery(struct stm_priv_segment_info_s *pseg);
 static void major_do_validation_and_minor_collections(void);


More information about the pypy-commit mailing list