[pypy-commit] stmgc c7-refactor: (arigo, Remi) missing: preventing a transaction from _starting_

arigo noreply at buildbot.pypy.org
Wed Feb 26 17:12:16 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r876:d6cbf69ae9ed
Date: 2014-02-26 17:12 +0100
http://bitbucket.org/pypy/stmgc/changeset/d6cbf69ae9ed/

Log:	(arigo, Remi) missing: preventing a transaction from _starting_ in
	inevitable mode if there is already an inevitable transaction
	running

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -151,8 +151,14 @@
 {
     mutex_lock_no_abort();
 
+  retry:
+    if (jmpbuf == NULL) {
+        wait_for_end_of_inevitable_transaction(false);
+    }
+
+    if (!acquire_thread_segment(tl))
+        goto retry;
     /* GS invalid before this point! */
-    acquire_thread_segment(tl);
 
     assert(STM_PSEGMENT->safe_point == SP_NO_TRANSACTION);
     assert(STM_PSEGMENT->transaction_state == TS_NONE);
@@ -376,6 +382,10 @@
         STM_PSEGMENT->overflow_number = highest_overflow_number;
     }
 
+    /* if we were inevitable, signal */
+    if (STM_PSEGMENT->transaction_state == TS_INEVITABLE)
+        cond_signal(C_INEVITABLE_DONE);
+
     /* done */
     _finish_transaction();
 
@@ -479,8 +489,6 @@
 
 void _stm_become_inevitable(char *msg)
 {
-    long i;
-
     mutex_lock();
     switch (STM_PSEGMENT->transaction_state) {
 
@@ -489,11 +497,7 @@
 
     case TS_REGULAR:
         /* become inevitable */
-        for (i = 0; i < NB_SEGMENTS; i++) {
-            if (get_priv_segment(i)->transaction_state == TS_INEVITABLE) {
-                abort_with_mutex();
-            }
-        }
+        wait_for_end_of_inevitable_transaction(true);
         STM_PSEGMENT->transaction_state = TS_INEVITABLE;
         break;
 
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -122,14 +122,13 @@
         stm_fatalerror("pthread_cond_signal/%d: %m\n", (int)ctype);
 }
 
-static void acquire_thread_segment(stm_thread_local_t *tl)
+static bool acquire_thread_segment(stm_thread_local_t *tl)
 {
     /* This function acquires a segment for the currently running thread,
        and set up the GS register if it changed. */
     assert(_has_mutex());
     assert(_is_tl_registered(tl));
 
- retry:;
     int num = tl->associated_segment_num;
     if (sync_ctl.in_use[num] == 0) {
         /* fast-path: we can get the same segment number than the one
@@ -157,7 +156,9 @@
        segment will do so by acquiring the mutex and calling
        cond_signal(C_RELEASE_THREAD_SEGMENT). */
     cond_wait_no_abort(C_RELEASE_THREAD_SEGMENT);
-    goto retry;
+
+    /* Return false to the caller, which will call us again */
+    return false;
 
  got_num:
     sync_ctl.in_use[num] = 1;
@@ -165,6 +166,7 @@
     assert(STM_SEGMENT->running_thread == NULL);
     STM_SEGMENT->running_thread = tl;
     STM_PSEGMENT->start_time = ++sync_ctl.global_time;
+    return true;
 }
 
 static void release_thread_segment(stm_thread_local_t *tl)
@@ -178,6 +180,28 @@
     sync_ctl.in_use[tl->associated_segment_num] = 0;
 }
 
+static void wait_for_end_of_inevitable_transaction(bool can_abort)
+{
+    assert(_has_mutex());
+
+    long i;
+  restart:
+    for (i = 0; i < NB_SEGMENTS; i++) {
+        if (get_priv_segment(i)->transaction_state == TS_INEVITABLE) {
+            if (can_abort) {
+                /* XXX should we wait here?  or abort?  or a mix?
+                   for now, always abort */
+                abort_with_mutex();
+                //cond_wait(C_INEVITABLE_DONE);
+            }
+            else {
+                cond_wait_no_abort(C_INEVITABLE_DONE);
+            }
+            goto restart;
+        }
+    }
+}
+
 static bool _running_transaction(void) __attribute__((unused));
 static bool _running_transaction(void)
 {
diff --git a/c7/stm/sync.h b/c7/stm/sync.h
--- a/c7/stm/sync.h
+++ b/c7/stm/sync.h
@@ -8,6 +8,7 @@
     C_RELEASE_THREAD_SEGMENT,
     C_SAFE_POINT,
     C_RESUME,
+    C_INEVITABLE_DONE,
     _C_TOTAL
 };
 static void mutex_lock(void);
@@ -21,8 +22,9 @@
 
 /* acquire and release one of the segments for running the given thread
    (must have the mutex acquired!) */
-static void acquire_thread_segment(stm_thread_local_t *tl);
+static bool acquire_thread_segment(stm_thread_local_t *tl);
 static void release_thread_segment(stm_thread_local_t *tl);
+static void wait_for_end_of_inevitable_transaction(bool can_abort);
 
 /* see the source for an exact description */
 static void wait_for_other_safe_points(int requested_safe_point_kind);


More information about the pypy-commit mailing list