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