Author: Armin Rigo <[email protected]>
Branch: stm-thread
Changeset: r55442:5e73ee52daf5
Date: 2012-06-06 18:36 +0200
http://bitbucket.org/pypy/pypy/changeset/5e73ee52daf5/

Log:    should_break_transaction(): give a configurable length limit.

diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py
--- a/pypy/module/thread/stm.py
+++ b/pypy/module/thread/stm.py
@@ -13,9 +13,20 @@
     can_cache = False
 
     def initialize(self, space):
-        pass
+        """NOT_RPYTHON: set up a mechanism to send to the C code the value
+        set by space.actionflag.setcheckinterval()."""
+        #
+        def setcheckinterval1(interval):
+            old_setcheckinterval(space.actionflag, interval)
+            self.configure_transaction_length(space)
+        #
+        old_setcheckinterval = space.actionflag.__class__.setcheckinterval
+        space.actionflag.setcheckinterval = setcheckinterval1
+        self.threads_running = False
 
     def setup_threads(self, space):
+        self.threads_running = True
+        self.configure_transaction_length(space)
         invoke_around_extcall(rstm.before_external_call,
                               rstm.after_external_call,
                               rstm.enter_callback_call,
@@ -24,6 +35,11 @@
     def reinit_threads(self, space):
         self.setup_threads(space)
 
+    def configure_transaction_length(self, space):
+        if self.threads_running:
+            interval = space.actionflag.getcheckinterval()
+            rstm.set_transaction_length(interval)
+
 
 class STMLock(ll_thread.Lock):
     def __init__(self, space, ll_lock):
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -17,6 +17,9 @@
     return we_are_translated() and (
         stmgcintf.StmOperations.should_break_transaction())
 
+def set_transaction_length(length):
+    stmgcintf.StmOperations.set_transaction_length(length)
+
 def increment_atomic():
     stmgcintf.StmOperations.add_atomic(+1)
 
diff --git a/pypy/translator/stm/src_stm/core.c 
b/pypy/translator/stm/src_stm/core.c
--- a/pypy/translator/stm/src_stm/core.c
+++ b/pypy/translator/stm/src_stm/core.c
@@ -736,6 +736,7 @@
 }
 
 static __thread long stm_atomic = 0;
+static long stm_regular_length_limit = LONG_MAX;
 
 void stm_add_atomic(long delta)
 {
@@ -750,7 +751,15 @@
 long stm_should_break_transaction(void)
 {
   struct tx_descriptor *d = thread_descriptor;
-  return !stm_atomic && is_inevitable(d);
+  return !stm_atomic && (is_inevitable(d) ||
+                         d->reads.size >= stm_regular_length_limit);
+}
+
+void stm_set_transaction_length(long length_max)
+{
+  struct tx_descriptor *d = thread_descriptor;
+  stm_try_inevitable(STM_EXPLAIN1("set_transaction_length"));
+  stm_regular_length_limit = length_max;
 }
 
 #define END_MARKER   ((void*)-8)   /* keep in sync with stmframework.py */
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -31,6 +31,7 @@
 void stm_add_atomic(long);
 long stm_get_atomic(void);
 long stm_should_break_transaction(void);
+void stm_set_transaction_length(long);
 
 void stm_perform_transaction(long(*)(void*, long), void*, void*);
 
diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py
--- a/pypy/translator/stm/stmgcintf.py
+++ b/pypy/translator/stm/stmgcintf.py
@@ -90,8 +90,5 @@
                                                 lltype.Signed],
                                                lltype.Void)
 
-    # if running in a transaction, make it inevitable
-    try_inevitable = smexternal('stm_try_inevitable', [], lltype.Void)
-
     # for testing
     abort_and_retry  = smexternal('stm_abort_and_retry', [], lltype.Void)
diff --git a/pypy/translator/stm/test/test_stmgcintf.c 
b/pypy/translator/stm/test/test_stmgcintf.c
--- a/pypy/translator/stm/test/test_stmgcintf.c
+++ b/pypy/translator/stm/test/test_stmgcintf.c
@@ -337,6 +337,37 @@
 
 /************************************************************/
 
+void should_break_transaction_1(void)
+{
+    assert(stm_should_break_transaction() == 0);
+    stm_set_transaction_length(10);   /* implies "becomes inevitable" */
+    assert(stm_should_break_transaction() == 1);
+}
+
+void should_break_transaction_2(void)
+{
+    S1 s1[15];
+    int i;
+    for (i=0; i<15; i++) {
+        s1[i].header.h_tid = GCFLAG_GLOBAL;
+        s1[i].header.h_version = NULL;
+        s1[i].value1 = 48+i;
+    }
+    for (i=0; i<15; i++) {
+        assert(stm_read_int1(s1+i, offsetof(S1, value1)) == 48+i);
+        assert(stm_should_break_transaction() == ((i+1) >= 10));
+    }
+}
+
+void test_should_break_transaction(void)
+{
+    assert(stm_in_transaction() == 0);
+    run_in_transaction(should_break_transaction_1, '.');
+    run_in_transaction(should_break_transaction_2, '.');
+}
+
+/************************************************************/
+
 
 #define XTEST(name)  if (!strcmp(argv[1], #name)) { test_##name(); return 0; }
 
@@ -355,6 +386,7 @@
     XTEST(size_getter);
     XTEST(copy_transactional_to_raw);
     XTEST(try_inevitable);
+    XTEST(should_break_transaction);
     printf("bad test name\n");
     return 1;
 }
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to