Author: Tobias Weber <tobias_webe...@gmx.de>
Branch: c8-tcp-style-trx-length
Changeset: r2082:39f4ab9d3e31
Date: 2017-07-01 19:15 +0200
http://bitbucket.org/pypy/stmgc/changeset/39f4ab9d3e31/

Log:    Merge fix for commit signalling to inevitable transactions

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -385,6 +385,14 @@
 static void readd_wb_executed_flags(void);
 static void check_all_write_barrier_flags(char *segbase, struct list_s *list);
 
+static void signal_commit_to_inevitable_transaction(void) {
+    struct stm_priv_segment_info_s* inevitable_segement = 
get_inevitable_thread_segment();
+    if (inevitable_segement != 0) {
+        // the inevitable thread is still running: set its "please commit" 
flag (is ignored by the inevitable thread if it is atomic)
+        inevitable_segement->commit_if_not_atomic = true;
+    }
+}
+
 static void wait_for_inevitable(void)
 {
     intptr_t detached = 0;
@@ -401,6 +409,8 @@
            try to detach an inevitable transaction regularly */
         detached = fetch_detached_transaction();
         if (detached == 0) {
+            // the inevitable trx was not detached or it was detached but is 
atomic
+            signal_commit_to_inevitable_transaction();
             EMIT_WAIT(STM_WAIT_OTHER_INEVITABLE);
             if (!cond_wait_timeout(C_SEGMENT_FREE_OR_SAFE_POINT_REQ, 0.00001))
                 goto wait_some_more;
@@ -1651,6 +1661,8 @@
             if (any_soon_finished_or_inevitable_thread_segment() &&
                     !safe_point_requested()) {
 
+                signal_commit_to_inevitable_transaction();
+
                 /* wait until C_SEGMENT_FREE_OR_SAFE_POINT_REQ is signalled */
                 EMIT_WAIT(STM_WAIT_OTHER_INEVITABLE);
                 if (!cond_wait_timeout(C_SEGMENT_FREE_OR_SAFE_POINT_REQ,
@@ -1694,6 +1706,7 @@
         stm_spin_loop();
     assert(_stm_detached_inevitable_from_thread == 0);
 
+    STM_PSEGMENT->commit_if_not_atomic = false;
     soon_finished_or_inevitable_thread_segment();
     STM_PSEGMENT->transaction_state = TS_INEVITABLE;
 
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -169,6 +169,9 @@
 
     /* For stm_enable_atomic() */
     uintptr_t atomic_nesting_levels;
+
+    // TODO signal flag that is checked in throw_away_nursery() for making 
immediate commit
+    bool commit_if_not_atomic;
 };
 
 enum /* safe_point */ {
diff --git a/c8/stm/detach.c b/c8/stm/detach.c
--- a/c8/stm/detach.c
+++ b/c8/stm/detach.c
@@ -215,6 +215,7 @@
     }
 }
 
+// TODO write tests, verify is working, verify no overflows with adaptive mode
 uintptr_t stm_is_atomic(stm_thread_local_t *tl)
 {
     assert(STM_SEGMENT->running_thread == tl);
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -548,6 +548,11 @@
     pseg->pub.nursery_current = (stm_char *)_stm_nursery_start;
     pseg->pub.nursery_mark -= nursery_used;
 
+    if (pseg->commit_if_not_atomic && 
pseg->pub.running_thread->self_or_0_if_atomic != 0) {
+        // not atomic and commit signalled by waiting thread: commit 
immediately
+        pseg->pub.nursery_mark = 0;
+    }
+
     /* free any object left from 'young_outside_nursery' */
     if (!tree_is_cleared(pseg->young_outside_nursery)) {
         wlog_t *item;
diff --git a/c8/stm/sync.c b/c8/stm/sync.c
--- a/c8/stm/sync.c
+++ b/c8/stm/sync.c
@@ -302,6 +302,19 @@
     return false;
 }
 
+static struct stm_priv_segment_info_s* get_inevitable_thread_segment(void)
+{
+    struct stm_priv_segment_info_s* segment;
+    int num;
+    for (num = 1; num < NB_SEGMENTS; num++) {
+        segment = get_priv_segment(num);
+        if (segment->transaction_state == TS_INEVITABLE) {
+            return segment;
+        }
+    }
+    return 0;
+}
+
 __attribute__((unused))
 static bool _seems_to_be_running_transaction(void)
 {
diff --git a/c8/stm/sync.h b/c8/stm/sync.h
--- a/c8/stm/sync.h
+++ b/c8/stm/sync.h
@@ -30,6 +30,7 @@
 static void release_thread_segment(stm_thread_local_t *tl);
 static void soon_finished_or_inevitable_thread_segment(void);
 static bool any_soon_finished_or_inevitable_thread_segment(void);
+static struct stm_priv_segment_info_s* get_inevitable_thread_segment(void);
 
 enum sync_type_e {
     STOP_OTHERS_UNTIL_MUTEX_UNLOCK,
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to