Author: Tobias Weber <[email protected]>
Branch: c8-long-transactions
Changeset: r2039:1b47d69c4988
Date: 2017-04-10 11:06 +0200
http://bitbucket.org/pypy/stmgc/changeset/1b47d69c4988/

Log:    Implement simple single thread mode that is activated if there are
        two or less segments in use at transaction start and sets the
        nursery mark to a large number, thereby reducing the number of
        commits

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1163,6 +1163,12 @@
 
     if (repeat_count == 0) {  /* else, 'nursery_mark' was already set
                                  in abort_data_structures_from_segment_num() */
+        if (number_of_segments_in_use() <= 2) {
+            /* TODO two is a hack b/c benchmarks have a main thread */
+            start_single_thread_mode();
+        } else if (stm_single_thread_mode_active) {
+            end_single_thread_mode();
+        }
         STM_SEGMENT->nursery_mark = ((stm_char *)_stm_nursery_start +
                                      stm_fill_mark_nursery_bytes);
     }
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -13,13 +13,24 @@
 
 static uintptr_t _stm_nursery_start;
 
+static bool stm_single_thread_mode_active = false;
 
-#define DEFAULT_FILL_MARK_NURSERY_BYTES   (NURSERY_SIZE / 4)
+#define SINGLE_THREAD_MODE_FILL_MARK_NURSERY_BYTES  (NURSERY_SIZE * 9999)
+#define DEFAULT_FILL_MARK_NURSERY_BYTES             (NURSERY_SIZE / 4)
 
 uintptr_t stm_fill_mark_nursery_bytes = DEFAULT_FILL_MARK_NURSERY_BYTES;
 
 /************************************************************/
 
+static void start_single_thread_mode(void) {
+    stm_single_thread_mode_active = true;
+    stm_fill_mark_nursery_bytes = SINGLE_THREAD_MODE_FILL_MARK_NURSERY_BYTES;
+}
+
+static void end_single_thread_mode(void) {
+    stm_fill_mark_nursery_bytes = DEFAULT_FILL_MARK_NURSERY_BYTES;
+    stm_single_thread_mode_active = false;
+}
 
 static void setup_nursery(void)
 {
diff --git a/c8/stm/nursery.h b/c8/stm/nursery.h
--- a/c8/stm/nursery.h
+++ b/c8/stm/nursery.h
@@ -9,6 +9,9 @@
 
 static uint32_t highest_overflow_number;
 
+static void start_single_thread_mode(void);
+static void end_single_thread_mode(void);
+
 static void _cards_cleared_in_object(struct stm_priv_segment_info_s *pseg, 
object_t *obj,
                                      bool strict);
 static void _reset_object_cards(struct stm_priv_segment_info_s *pseg,
diff --git a/c8/stm/sync.c b/c8/stm/sync.c
--- a/c8/stm/sync.c
+++ b/c8/stm/sync.c
@@ -176,6 +176,16 @@
 
 /************************************************************/
 
+static uint8_t number_of_segments_in_use(void) {
+    uint8_t result = 0;
+    int num;
+    for (num = 1; num < NB_SEGMENTS; num++) {
+        if (sync_ctl.in_use1[num] > 0) {
+            result++;
+        }
+    }
+    return result;
+}
 
 #if 0
 void stm_wait_for_current_inevitable_transaction(void)
@@ -202,7 +212,6 @@
 }
 #endif
 
-
 static void acquire_thread_segment(stm_thread_local_t *tl)
 {
     /* This function acquires a segment for the currently running thread,
diff --git a/c8/stm/sync.h b/c8/stm/sync.h
--- a/c8/stm/sync.h
+++ b/c8/stm/sync.h
@@ -22,6 +22,7 @@
 static void set_gs_register(char *value);
 static void ensure_gs_register(long segnum);
 
+static uint8_t number_of_segments_in_use(void);
 
 /* acquire and release one of the segments for running the given thread
    (must have the mutex acquired!) */
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to