[pypy-commit] pypy stm: (arigo, antocuni): start to write the RPython level interface for using transactions in rlib/rstm.py. Move the compiled tests from translator/stm/test_transform.py to rlib/test/test_rstm.py
antocuni
noreply at buildbot.pypy.org
Mon Jan 16 18:15:39 CET 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: stm
Changeset: r51355:1aa99f2f035f
Date: 2012-01-16 18:06 +0100
http://bitbucket.org/pypy/pypy/changeset/1aa99f2f035f/
Log: (arigo, antocuni): start to write the RPython level interface for
using transactions in rlib/rstm.py. Move the compiled tests from
translator/stm/test_transform.py to rlib/test/test_rstm.py
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/rstm.py
@@ -0,0 +1,38 @@
+from pypy.rlib.objectmodel import specialize, we_are_translated, keepalive_until_here
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.annlowlevel import (cast_base_ptr_to_instance,
+ cast_instance_to_base_ptr,
+ llhelper)
+from pypy.translator.stm import _rffi_stm
+
+ at specialize.memo()
+def _get_stm_callback(func, argcls):
+ def _stm_callback(llarg):
+ 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)
+ assert res is None
+ return lltype.nullptr(rffi.VOIDP.TO)
+ return _stm_callback
+
+ at specialize.arg(0, 1)
+def stm_perform_transaction(func, argcls, arg):
+ assert isinstance(arg, argcls)
+ assert argcls._alloc_nonmovable_
+ if we_are_translated():
+ llarg = cast_instance_to_base_ptr(arg)
+ llarg = rffi.cast(rffi.VOIDP, llarg)
+ else:
+ # only for tests
+ lltype.TLS.stm_callback_arg = arg
+ llarg = lltype.nullptr(rffi.VOIDP.TO)
+ callback = _get_stm_callback(func, argcls)
+ llcallback = llhelper(_rffi_stm.CALLBACK, callback)
+ _rffi_stm.perform_transaction(llcallback, llarg)
+ keepalive_until_here(arg)
+
+stm_descriptor_init = _rffi_stm.descriptor_init
+stm_descriptor_done = _rffi_stm.descriptor_done
diff --git a/pypy/rlib/test/test_rstm.py b/pypy/rlib/test/test_rstm.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/test/test_rstm.py
@@ -0,0 +1,51 @@
+from pypy.rlib.debug import debug_print
+from pypy.rlib import rstm
+from pypy.translator.c.test.test_standalone import StandaloneTests
+
+def test_stm_perform_transaction():
+ class Arg(object):
+ _alloc_nonmovable_ = True
+
+ def setx(arg):
+ arg.x = 42
+
+ arg = Arg()
+ rstm.stm_descriptor_init()
+ rstm.stm_perform_transaction(setx, Arg, arg)
+ rstm.stm_descriptor_done()
+ assert arg.x == 42
+
+
+class CompiledSTMTests(StandaloneTests):
+ gc = "none"
+
+ def compile(self, entry_point):
+ from pypy.config.pypyoption import get_pypy_config
+ self.config = get_pypy_config(translating=True)
+ self.config.translation.stm = True
+ self.config.translation.gc = self.gc
+ #
+ # Prevent the RaiseAnalyzer from just emitting "WARNING: Unknown
+ # operation". We want instead it to crash.
+ from pypy.translator.backendopt.canraise import RaiseAnalyzer
+ RaiseAnalyzer.fail_on_unknown_operation = True
+ try:
+ res = StandaloneTests.compile(self, entry_point, debug=True)
+ finally:
+ RaiseAnalyzer.fail_on_unknown_operation = False
+ return res
+
+
+class TestTransformSingleThread(CompiledSTMTests):
+
+ def test_no_pointer_operations(self):
+ def simplefunc(argv):
+ i = 0
+ while i < 100:
+ i += 3
+ debug_print(i)
+ return 0
+ t, cbuilder = self.compile(simplefunc)
+ dataout, dataerr = cbuilder.cmdexec('', err=True)
+ assert dataout == ''
+ assert '102' in dataerr.splitlines()
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
@@ -676,10 +676,8 @@
void* stm_perform_transaction(void*(*callback)(void*), void *arg)
{
void *result;
-#ifdef RPY_STM_ASSERT
/* you need to call descriptor_init() before calling stm_perform_transaction */
assert(thread_descriptor != NULL);
-#endif
STM_begin_transaction();
result = callback(arg);
stm_commit_transaction();
diff --git a/pypy/translator/stm/test/test_transform.py b/pypy/translator/stm/test/test_transform.py
--- a/pypy/translator/stm/test/test_transform.py
+++ b/pypy/translator/stm/test/test_transform.py
@@ -3,9 +3,6 @@
from pypy.objspace.flow.model import summary
from pypy.translator.stm.llstminterp import eval_stm_graph
from pypy.translator.stm.transform import transform_graph
-##from pypy.translator.stm import rstm
-from pypy.translator.c.test.test_standalone import StandaloneTests
-from pypy.rlib.debug import debug_print
from pypy.conftest import option
@@ -179,96 +176,3 @@
res = eval_stm_graph(interp, graph, [p], stm_mode="regular_transaction",
final_stm_mode="inevitable_transaction")
assert res == 42
-
-# ____________________________________________________________
-
-class CompiledSTMTests(StandaloneTests):
- gc = "none"
-
- def compile(self, entry_point):
- from pypy.config.pypyoption import get_pypy_config
- self.config = get_pypy_config(translating=True)
- self.config.translation.stm = True
- self.config.translation.gc = self.gc
- #
- # Prevent the RaiseAnalyzer from just emitting "WARNING: Unknown
- # operation". We want instead it to crash.
- from pypy.translator.backendopt.canraise import RaiseAnalyzer
- RaiseAnalyzer.fail_on_unknown_operation = True
- try:
- res = StandaloneTests.compile(self, entry_point, debug=True)
- finally:
- RaiseAnalyzer.fail_on_unknown_operation = False
- return res
-
-
-class TestTransformSingleThread(CompiledSTMTests):
-
- def test_no_pointer_operations(self):
- def simplefunc(argv):
- i = 0
- while i < 100:
- i += 3
- debug_print(i)
- return 0
- t, cbuilder = self.compile(simplefunc)
- dataout, dataerr = cbuilder.cmdexec('', err=True)
- assert dataout == ''
- assert '102' in dataerr.splitlines()
-
- def test_fails_when_nonbalanced_begin(self):
- def simplefunc(argv):
- rstm.begin_transaction()
- return 0
- t, cbuilder = self.compile(simplefunc)
- cbuilder.cmdexec('', expect_crash=True)
-
- def test_fails_when_nonbalanced_commit(self):
- def simplefunc(argv):
- rstm.commit_transaction()
- rstm.commit_transaction()
- return 0
- t, cbuilder = self.compile(simplefunc)
- cbuilder.cmdexec('', expect_crash=True)
-
- def test_begin_inevitable_transaction(self):
- def simplefunc(argv):
- rstm.commit_transaction()
- rstm.begin_inevitable_transaction()
- return 0
- t, cbuilder = self.compile(simplefunc)
- cbuilder.cmdexec('')
-
- def test_transaction_boundary_1(self):
- def simplefunc(argv):
- rstm.transaction_boundary()
- return 0
- t, cbuilder = self.compile(simplefunc)
- cbuilder.cmdexec('')
-
- def test_transaction_boundary_2(self):
- def simplefunc(argv):
- rstm.transaction_boundary()
- rstm.transaction_boundary()
- rstm.transaction_boundary()
- return 0
- t, cbuilder = self.compile(simplefunc)
- cbuilder.cmdexec('')
-
- def test_transaction_boundary_3(self):
- def simplefunc(argv):
- s1 = argv[0]
- debug_print('STEP1:', len(s1))
- rstm.transaction_boundary()
- rstm.transaction_boundary()
- rstm.transaction_boundary()
- debug_print('STEP2:', len(s1))
- return 0
- t, cbuilder = self.compile(simplefunc)
- data, err = cbuilder.cmdexec('', err=True)
- lines = err.splitlines()
- steps = [(line[:6], line[6:])
- for line in lines if line.startswith('STEP')]
- steps = zip(*steps)
- assert steps[0] == ('STEP1:', 'STEP2:')
- assert steps[1][0] == steps[1][1]
More information about the pypy-commit
mailing list