[pypy-commit] pypy stm: Add an argument to the callback invoked by stm_perform_transaction:
arigo
noreply at buildbot.pypy.org
Sun Jan 22 10:53:05 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r51626:b8a1df61795a
Date: 2012-01-22 10:51 +0100
http://bitbucket.org/pypy/pypy/changeset/b8a1df61795a/
Log: Add an argument to the callback invoked by stm_perform_transaction:
a retry counter starting at 0.
diff --git a/pypy/module/transaction/interp_transaction.py b/pypy/module/transaction/interp_transaction.py
--- a/pypy/module/transaction/interp_transaction.py
+++ b/pypy/module/transaction/interp_transaction.py
@@ -84,11 +84,18 @@
self.w_callback = w_callback
self.args = args
+ def register(self):
+ id = threadintf.thread_id()
+ state.pending_lists[id].append(self)
+
def run(self):
rstm.perform_transaction(Pending._run_in_transaction, Pending, self)
@staticmethod
- def _run_in_transaction(pending):
+ def _run_in_transaction(pending, retry_counter):
+ if retry_counter > 0:
+ self.register() # retrying: will be done later, try others first
+ return
if state.got_exception is not None:
return # return early if there is already a 'got_exception'
try:
@@ -99,8 +106,7 @@
def add(space, w_callback, __args__):
- id = threadintf.thread_id()
- state.pending_lists[id].append(Pending(w_callback, __args__))
+ Pending(w_callback, __args__).register()
def add_list(new_pending_list):
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -10,13 +10,13 @@
@specialize.memo()
def _get_stm_callback(func, argcls):
- def _stm_callback(llarg):
+ def _stm_callback(llarg, retry_counter):
if we_are_translated():
llarg = rffi.cast(rclass.OBJECTPTR, llarg)
arg = cast_base_ptr_to_instance(argcls, llarg)
else:
arg = lltype.TLS.stm_callback_arg
- res = func(arg)
+ res = func(arg, retry_counter)
assert res is None
return lltype.nullptr(rffi.VOIDP.TO)
return _stm_callback
diff --git a/pypy/rlib/test/test_rstm.py b/pypy/rlib/test/test_rstm.py
--- a/pypy/rlib/test/test_rstm.py
+++ b/pypy/rlib/test/test_rstm.py
@@ -7,7 +7,7 @@
class Arg(object):
_alloc_nonmovable_ = True
-def setx(arg):
+def setx(arg, retry_counter):
debug_print(arg.x)
assert rstm.debug_get_state() == 1
if arg.x == 303:
diff --git a/pypy/translator/stm/_rffi_stm.py b/pypy/translator/stm/_rffi_stm.py
--- a/pypy/translator/stm/_rffi_stm.py
+++ b/pypy/translator/stm/_rffi_stm.py
@@ -32,7 +32,7 @@
stm_write_word = llexternal('stm_write_word', [SignedP, lltype.Signed],
lltype.Void)
-CALLBACK = lltype.Ptr(lltype.FuncType([rffi.VOIDP], rffi.VOIDP))
+CALLBACK = lltype.Ptr(lltype.FuncType([rffi.VOIDP, lltype.Signed], rffi.VOIDP))
stm_perform_transaction = llexternal('stm_perform_transaction',
[CALLBACK, rffi.VOIDP], rffi.VOIDP)
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -622,16 +622,20 @@
return d->end_time;
}
-void* stm_perform_transaction(void*(*callback)(void*), void *arg)
+void* stm_perform_transaction(void*(*callback)(void*, long), void *arg)
{
void *result;
jmp_buf _jmpbuf;
+ volatile long v_counter = 0;
+ long counter;
/* you need to call descriptor_init() before calling
stm_perform_transaction() */
assert(thread_descriptor != NULL_TX);
setjmp(_jmpbuf);
begin_transaction(&_jmpbuf);
- result = callback(arg);
+ counter = v_counter;
+ v_counter = counter + 1;
+ result = callback(arg, counter);
commit_transaction();
return result;
}
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
@@ -22,7 +22,7 @@
void stm_descriptor_init(void);
void stm_descriptor_done(void);
-void* stm_perform_transaction(void*(*)(void*), void*);
+void* stm_perform_transaction(void*(*)(void*, long), void*);
long stm_read_word(long* addr);
void stm_write_word(long* addr, long val);
void stm_try_inevitable(STM_CCHARP1(why));
diff --git a/pypy/translator/stm/test/targetdemo.py b/pypy/translator/stm/test/targetdemo.py
--- a/pypy/translator/stm/test/targetdemo.py
+++ b/pypy/translator/stm/test/targetdemo.py
@@ -20,7 +20,7 @@
_alloc_nonmovable_ = True
-def add_at_end_of_chained_list(arg):
+def add_at_end_of_chained_list(arg, retry_counter):
node = arg.anchor
value = arg.value
x = Node(value)
@@ -52,7 +52,7 @@
print "check ok!"
-def increment_done(arg):
+def increment_done(arg, retry_counter):
print "thread done."
glob.done += 1
diff --git a/pypy/translator/stm/test/test_funcgen.py b/pypy/translator/stm/test/test_funcgen.py
--- a/pypy/translator/stm/test/test_funcgen.py
+++ b/pypy/translator/stm/test/test_funcgen.py
@@ -93,7 +93,7 @@
return a
a_prebuilt = make_a_1()
-def _play_with_getfield(dummy_arg):
+def _play_with_getfield(dummy_arg, retry_counter):
a = a_prebuilt
assert a.x == -611
assert a.c1 == '/'
@@ -106,7 +106,7 @@
assert float(a.sb) == float(rs1b)
return NULL
-def _play_with_setfields(dummy_arg):
+def _play_with_setfields(dummy_arg, retry_counter):
a = a_prebuilt
#
a.x = 12871981
@@ -125,10 +125,10 @@
a.sb = rs2b
# read the values which have not been commited yet, but are local to the
# transaction
- _check_values_of_fields(dummy_arg)
+ _check_values_of_fields(dummy_arg, retry_counter)
return NULL
-def _check_values_of_fields(dummy_arg):
+def _check_values_of_fields(dummy_arg, retry_counter):
a = a_prebuilt
assert a.x == 12871981
assert a.c1 == '('
@@ -162,14 +162,14 @@
array[i] = rffi.cast(lltype.typeOf(array).TO.OF, newvalues[i])
change._annspecialcase_ = 'specialize:ll'
-def _play_with_getarrayitem(dummy_arg):
+def _play_with_getarrayitem(dummy_arg, retry_counter):
check(prebuilt_array_signed, [1, 10, -1, -10, 42])
check(prebuilt_array_char, [chr(1), chr(10), chr(255),
chr(246), chr(42)])
return NULL
-def _play_with_setarrayitem_1(dummy_arg):
+def _play_with_setarrayitem_1(dummy_arg, retry_counter):
change(prebuilt_array_signed, [500000, -10000000, 3])
check(prebuilt_array_signed, [500000, -10000000, 3, -10, 42])
prebuilt_array_char[0] = 'A'
@@ -180,7 +180,7 @@
check(prebuilt_array_char, ['A', chr(10), chr(255), 'B', 'C'])
return NULL
-def _play_with_setarrayitem_2(dummy_arg):
+def _play_with_setarrayitem_2(dummy_arg, retry_counter):
check(prebuilt_array_char, ['A', chr(10), chr(255), 'B', 'C'])
prebuilt_array_char[1] = 'D'
check(prebuilt_array_char, ['A', 'D', chr(255), 'B', 'C'])
@@ -188,7 +188,7 @@
check(prebuilt_array_char, ['A', 'D', 'E', 'B', 'C'])
return NULL
-def _play_with_setarrayitem_3(dummy_arg):
+def _play_with_setarrayitem_3(dummy_arg, retry_counter):
check(prebuilt_array_char, ['A', 'D', 'E', 'B', 'C'])
return NULL
@@ -222,14 +222,14 @@
array[i].y = rffi.cast(lltype.typeOf(array).TO.OF.y, newvalues2[i])
change2._annspecialcase_ = 'specialize:ll'
-def _play_with_getinteriorfield(dummy_arg):
+def _play_with_getinteriorfield(dummy_arg, retry_counter):
check2(prebuilt_array_signed_signed, [1, -1, -50], [10, 20, -30])
check2(prebuilt_array_char_char, [chr(1), chr(255), chr(206)],
[chr(10), chr(20), chr(226)])
return NULL
-def _play_with_setinteriorfield_1(dummy_arg):
+def _play_with_setinteriorfield_1(dummy_arg, retry_counter):
change2(prebuilt_array_signed_signed, [500000, -10000000], [102101202])
check2(prebuilt_array_signed_signed, [500000, -10000000, -50],
[102101202, 20, -30])
@@ -238,7 +238,7 @@
['b', chr(20), chr(226)])
return NULL
-def _play_with_setinteriorfield_2(dummy_arg):
+def _play_with_setinteriorfield_2(dummy_arg, retry_counter):
check2(prebuilt_array_signed_signed, [500000, -10000000, -50],
[102101202, 20, -30])
check2(prebuilt_array_char_char, ['a', chr(255), chr(206)],
@@ -253,7 +253,7 @@
def test_getfield_all_sizes(self):
def do_stm_getfield(argv):
- _play_with_getfield(None)
+ _play_with_getfield(None, 0)
return 0
t, cbuilder = self.compile(do_stm_getfield)
cbuilder.cmdexec('')
@@ -272,7 +272,7 @@
def do_stm_getfield(argv):
stm_descriptor_init()
# we have a descriptor, but we don't call it in a transaction
- _play_with_getfield(None)
+ _play_with_getfield(None, 0)
stm_descriptor_done()
return 0
t, cbuilder = self.compile(do_stm_getfield)
@@ -280,7 +280,7 @@
def test_setfield_all_sizes(self):
def do_stm_setfield(argv):
- _play_with_setfields(None)
+ _play_with_setfields(None, 0)
return 0
t, cbuilder = self.compile(do_stm_setfield)
cbuilder.cmdexec('')
@@ -301,7 +301,7 @@
def test_setfield_all_sizes_outside_transaction(self):
def do_stm_setfield(argv):
stm_descriptor_init()
- _play_with_setfields(None)
+ _play_with_setfields(None, 0)
stm_descriptor_done()
return 0
t, cbuilder = self.compile(do_stm_setfield)
@@ -309,7 +309,7 @@
def test_getarrayitem_all_sizes(self):
def do_stm_getarrayitem(argv):
- _play_with_getarrayitem(None)
+ _play_with_getarrayitem(None, 0)
return 0
t, cbuilder = self.compile(do_stm_getarrayitem)
cbuilder.cmdexec('')
@@ -327,9 +327,9 @@
def test_setarrayitem_all_sizes(self):
def do_stm_setarrayitem(argv):
- _play_with_setarrayitem_1(None)
- _play_with_setarrayitem_2(None)
- _play_with_setarrayitem_3(None)
+ _play_with_setarrayitem_1(None, 0)
+ _play_with_setarrayitem_2(None, 0)
+ _play_with_setarrayitem_3(None, 0)
return 0
t, cbuilder = self.compile(do_stm_setarrayitem)
cbuilder.cmdexec('')
@@ -351,7 +351,7 @@
def test_getinteriorfield_all_sizes(self):
def do_stm_getinteriorfield(argv):
- _play_with_getinteriorfield(None)
+ _play_with_getinteriorfield(None, 0)
return 0
t, cbuilder = self.compile(do_stm_getinteriorfield)
cbuilder.cmdexec('')
@@ -369,8 +369,8 @@
def test_setinteriorfield_all_sizes(self):
def do_stm_setinteriorfield(argv):
- _play_with_setinteriorfield_1(None)
- _play_with_setinteriorfield_2(None)
+ _play_with_setinteriorfield_1(None, 0)
+ _play_with_setinteriorfield_2(None, 0)
return 0
t, cbuilder = self.compile(do_stm_setinteriorfield)
cbuilder.cmdexec('')
diff --git a/pypy/translator/stm/test/test_llstm.py b/pypy/translator/stm/test/test_llstm.py
--- a/pypy/translator/stm/test/test_llstm.py
+++ b/pypy/translator/stm/test/test_llstm.py
@@ -19,8 +19,9 @@
rs1b = r_singlefloat(40.121)
rs2b = r_singlefloat(-9e9)
-def callback1(a):
+def callback1(a, retry_counter):
a = rffi.cast(lltype.Ptr(A), a)
+ assert retry_counter == a.y # non-transactionally
assert a.x == -611
assert a.c1 == '/'
assert a.c2 == '\\'
@@ -76,7 +77,7 @@
assert a.y == 10
lltype.free(a, flavor='raw')
-def callback2(a):
+def callback2(a, retry_counter):
a = rffi.cast(lltype.Ptr(A), a)
assert a.x == -611
assert a.c1 == '&'
diff --git a/pypy/translator/stm/test/test_rffi_stm.py b/pypy/translator/stm/test/test_rffi_stm.py
--- a/pypy/translator/stm/test/test_rffi_stm.py
+++ b/pypy/translator/stm/test/test_rffi_stm.py
@@ -6,7 +6,7 @@
stm_descriptor_done()
def test_stm_perform_transaction():
- def callback1(x):
+ def callback1(x, retry_counter):
return lltype.nullptr(rffi.VOIDP.TO)
stm_descriptor_init()
stm_perform_transaction(llhelper(CALLBACK, callback1),
@@ -17,7 +17,8 @@
A = lltype.Struct('A', ('x', lltype.Signed), ('y', lltype.Signed))
a = lltype.malloc(A, immortal=True, flavor='raw')
a.y = 0
- def callback1(x):
+ def callback1(x, retry_counter):
+ assert retry_counter == a.y
if a.y < 10:
a.y += 1 # non-transactionally
stm_abort_and_retry()
@@ -35,7 +36,8 @@
a = lltype.malloc(A, immortal=True, flavor='raw')
a.x = -611
a.y = 0
- def callback1(x):
+ def callback1(x, retry_counter):
+ assert retry_counter == a.y
assert a.x == -611
p = lltype.direct_fieldptr(a, 'x')
p = rffi.cast(SignedP, p)
@@ -55,7 +57,7 @@
assert a.x == 420
def test_stm_debug_get_state():
- def callback1(x):
+ def callback1(x, retry_counter):
assert stm_debug_get_state() == 1
stm_try_inevitable()
assert stm_debug_get_state() == 2
More information about the pypy-commit
mailing list