Author: Antonio Cuni <anto.c...@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 + +@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 + +@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] _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit