[pypy-commit] pypy stm-gc: Start to kill old code and port some tests

arigo noreply at buildbot.pypy.org
Sun Feb 12 11:54:35 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52385:712f58081b5c
Date: 2012-02-12 11:40 +0100
http://bitbucket.org/pypy/pypy/changeset/712f58081b5c/

Log:	Start to kill old code and port some tests

diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -19,16 +19,6 @@
 GCFLAG_HAS_SHADOW = first_gcflag << 2
 GCFLAG_FIXED_HASH = first_gcflag << 3
 
-PRIMITIVE_SIZES   = {1: lltype.Char,
-                     2: rffi.SHORT,
-                     4: rffi.INT,
-                     8: lltype.SignedLongLong,
-                     '8f': rffi.DOUBLE,
-                     '4f': rffi.FLOAT}
-
-CALLBACK = lltype.Ptr(lltype.FuncType([llmemory.Address] * 3, lltype.Void))
-GETSIZE  = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
-
 
 def always_inline(fn):
     fn._always_inline_ = True
diff --git a/pypy/translator/stm/TODO.txt b/pypy/translator/stm/TODO.txt
deleted file mode 100644
--- a/pypy/translator/stm/TODO.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-* turn calls to stm_read_word() to:
-    if (d) x = stm_read_word(a); else x = *a;
-
-  this way, gcc will optimize:
-    if (d) x = stm_read_word(a); else x = *a;
-    if (d) y = stm_read_word(b); else y = *b;
-  to check !d only once if it is null
-
-
-* PyFrames are accessed directly:
-
-  - make the case of concurrent accesses to the same generator safe
-  - make the rare other cases of concurrent accesses safe
diff --git a/pypy/translator/stm/_rffi_stm.py b/pypy/translator/stm/_rffi_stm.py
deleted file mode 100644
--- a/pypy/translator/stm/_rffi_stm.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import py
-import os
-from pypy.tool.autopath import pypydir
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.rlib.rarithmetic import LONG_BIT
-
-
-cdir = py.path.local(pypydir) / 'translator' / 'stm'
-cdir2 = py.path.local(pypydir) / 'translator' / 'c'
-
-eci = ExternalCompilationInfo(
-    include_dirs = [cdir, cdir2],
-    includes = ['src_stm/et.h', 'src_stm/et.c'],
-    pre_include_bits = ['#define PYPY_LONG_BIT %d' % LONG_BIT],
-    separate_module_sources = ['\n'],    # hack for test_rffi_stm
-)
-
-def llexternal(name, args, result, **kwds):
-    return rffi.llexternal(name, args, result, compilation_info=eci,
-                           _nowrapper=True, **kwds)
-
-SignedP = rffi.CArrayPtr(lltype.Signed)
-
-
-stm_descriptor_init = llexternal('stm_descriptor_init', [], lltype.Void)
-stm_descriptor_done = llexternal('stm_descriptor_done', [], lltype.Void)
-
-stm_try_inevitable = llexternal('stm_try_inevitable', [], lltype.Void)
-
-stm_read_word = llexternal('stm_read_word', [SignedP], lltype.Signed)
-stm_write_word = llexternal('stm_write_word', [SignedP, lltype.Signed],
-                            lltype.Void)
-
-CALLBACK = lltype.Ptr(lltype.FuncType([rffi.VOIDP, lltype.Signed], rffi.VOIDP))
-stm_perform_transaction = llexternal('stm_perform_transaction',
-                                     [CALLBACK, rffi.VOIDP], rffi.VOIDP)
-
-stm_abort_and_retry = llexternal('stm_abort_and_retry', [], lltype.Void)
-stm_debug_get_state = llexternal('stm_debug_get_state', [], lltype.Signed)
-stm_thread_id       = llexternal('stm_thread_id',       [], lltype.Signed)
diff --git a/pypy/translator/stm/llstm.py b/pypy/translator/stm/llstm.py
deleted file mode 100644
--- a/pypy/translator/stm/llstm.py
+++ /dev/null
@@ -1,177 +0,0 @@
-"""
-This file is mostly here for testing.  Usually, transform.py will transform
-the getfields (etc) that occur in the graphs directly into stm_getfields,
-which are operations that are recognized by the C backend.  See funcgen.py
-which contains similar logic, which is run by the C backend.
-"""
-import sys
-from pypy.rpython.lltypesystem import lltype, rffi, rclass
-from pypy.rpython.extregistry import ExtRegistryEntry
-from pypy.translator.stm import _rffi_stm
-from pypy.annotation import model as annmodel
-from pypy.objspace.flow.model import Constant
-from pypy.rlib.rarithmetic import r_uint, r_ulonglong
-from pypy.rlib import longlong2float
-from pypy.rlib.objectmodel import specialize
-from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
-from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
-
-size_of_voidp = rffi.sizeof(rffi.VOIDP)
-assert size_of_voidp & (size_of_voidp - 1) == 0
-
-assert sys.byteorder == 'little'   # xxx fix here, in funcgen.py, and in et.c
-
-
-def stm_getfield(structptr, fieldname):
-    "NOT_RPYTHON"
-    STRUCT = lltype.typeOf(structptr).TO
-    FIELD = getattr(STRUCT, fieldname)
-    p = lltype.direct_fieldptr(structptr, fieldname)
-    p = rffi.cast(lltype.Signed, p)
-    misalignment = p & (size_of_voidp - 1)
-    fieldsize = rffi.sizeof(FIELD)
-    p = rffi.cast(_rffi_stm.SignedP, p - misalignment)
-    if fieldsize >= size_of_voidp:
-        assert misalignment == 0
-        if fieldsize == size_of_voidp:
-            res = _rffi_stm.stm_read_word(p)
-        elif fieldsize == 8:    # 32-bit only: read a 64-bit field
-            res0 = r_uint(_rffi_stm.stm_read_word(p))
-            res1 = r_uint(_rffi_stm.stm_read_word(rffi.ptradd(p, 1)))
-            res = (r_ulonglong(res1) << 32) | res0
-        else:
-            raise NotImplementedError(fieldsize)
-        if FIELD == lltype.Float:
-            return longlong2float.longlong2float(rffi.cast(rffi.LONGLONG, res))
-    else:
-        assert misalignment + fieldsize <= size_of_voidp
-        res = _rffi_stm.stm_read_word(p)
-        res = res >> (misalignment * 8)
-    if FIELD == lltype.SingleFloat:
-        return longlong2float.uint2singlefloat(rffi.cast(rffi.UINT, res))
-    return rffi.cast(FIELD, res)
-
-def stm_setfield(structptr, fieldname, newvalue):
-    "NOT_RPYTHON"
-    STRUCT = lltype.typeOf(structptr).TO
-    FIELD = getattr(STRUCT, fieldname)
-    p = lltype.direct_fieldptr(structptr, fieldname)
-    p = rffi.cast(lltype.Signed, p)
-    misalignment = p & (size_of_voidp - 1)
-    fieldsize = rffi.sizeof(FIELD)
-    #print 'setfield %x size %d:' % (p, fieldsize),
-    p = rffi.cast(_rffi_stm.SignedP, p - misalignment)
-    if FIELD == lltype.SingleFloat:
-        newvalue = longlong2float.singlefloat2uint(newvalue)
-    if fieldsize >= size_of_voidp:
-        assert misalignment == 0
-        if FIELD == lltype.Float:
-            newvalue = longlong2float.float2longlong(newvalue)
-        if fieldsize == size_of_voidp:
-            _rffi_stm.stm_write_word(p, rffi.cast(lltype.Signed, newvalue))
-        elif fieldsize == 8:    # 32-bit only: write a 64-bit field
-            _rffi_stm.stm_write_word(p, rffi.cast(lltype.Signed, newvalue))
-            p = rffi.ptradd(p, 1)
-            newvalue = rffi.cast(lltype.SignedLongLong, newvalue) >> 32
-            _rffi_stm.stm_write_word(p, rffi.cast(lltype.Signed, newvalue))
-        else:
-            raise NotImplementedError(fieldsize)
-        #print 'ok'
-    else:
-        # bah, must read the complete word in order to modify only a part
-        assert misalignment + fieldsize <= size_of_voidp
-        val = rffi.cast(lltype.Signed, newvalue)
-        val = val << (misalignment * 8)
-        word = _rffi_stm.stm_read_word(p)
-        mask = ((1 << (fieldsize * 8)) - 1) << (misalignment * 8)
-        val = (val & mask) | (word & ~mask)
-        #print 'getting %x, mask=%x, replacing with %x' % (word, mask, val)
-        _rffi_stm.stm_write_word(p, val)
-
-def stm_getarrayitem(arrayptr, index):
-    "NOT_RPYTHON"
-    raise NotImplementedError("sorry")
-
-def stm_setarrayitem(arrayptr, index, value):
-    "NOT_RPYTHON"
-    raise NotImplementedError("sorry")
-
-def stm_become_inevitable(why):
-    "NOT_RPYTHON"
-    raise NotImplementedError("sorry")
-
-# ____________________________________________________________
-
-
-class ExtEntry(ExtRegistryEntry):
-    _about_ = stm_getfield
-
-    def compute_result_annotation(self, s_structptr, s_fieldname):
-        return s_structptr.getattr(s_fieldname)
-
-    def specialize_call(self, hop):
-        r_structptr = hop.args_r[0]
-        v_structptr = hop.inputarg(r_structptr, arg=0)
-        fieldname = hop.args_v[1].value
-        c_fieldname = hop.inputconst(lltype.Void, fieldname)
-        hop.exception_cannot_occur()
-        return hop.genop('stm_getfield', [v_structptr, c_fieldname],
-                         resulttype = hop.r_result)
-
-
-class ExtEntry(ExtRegistryEntry):
-    _about_ = stm_setfield
-
-    def compute_result_annotation(self, s_structptr, s_fieldname, s_newvalue):
-        return None
-
-    def specialize_call(self, hop):
-        r_structptr = hop.args_r[0]
-        v_structptr = hop.inputarg(r_structptr, arg=0)
-        fieldname = hop.args_v[1].value
-        v_newvalue = hop.inputarg(hop.args_r[2], arg=2)
-        c_fieldname = hop.inputconst(lltype.Void, fieldname)
-        hop.exception_cannot_occur()
-        hop.genop('stm_setfield', [v_structptr, c_fieldname, v_newvalue])
-
-
-class ExtEntry(ExtRegistryEntry):
-    _about_ = stm_getarrayitem
-
-    def compute_result_annotation(self, s_arrayptr, s_index):
-        from pypy.tool.pairtype import pair
-        return pair(s_arrayptr, s_index).getitem()
-
-    def specialize_call(self, hop):
-        r_arrayptr = hop.args_r[0]
-        v_arrayptr, v_index = hop.inputargs(r_arrayptr, lltype.Signed)
-        hop.exception_cannot_occur()
-        return hop.genop('stm_getarrayitem', [v_arrayptr, v_index],
-                         resulttype = hop.r_result)
-
-
-class ExtEntry(ExtRegistryEntry):
-    _about_ = stm_setarrayitem
-
-    def compute_result_annotation(self, s_arrayptr, s_index, s_newvalue):
-        return None
-
-    def specialize_call(self, hop):
-        r_arrayptr = hop.args_r[0]
-        v_arrayptr, v_index, v_newvalue = hop.inputargs(r_arrayptr,
-                                                        lltype.Signed,
-                                                        hop.args_r[2])
-        hop.exception_cannot_occur()
-        hop.genop('stm_setarrayitem', [v_arrayptr, v_index, v_newvalue])
-
-
-class ExtEntry(ExtRegistryEntry):
-    _about_ = stm_become_inevitable
-
-    def compute_result_annotation(self, s_why):
-        return None
-
-    def specialize_call(self, hop):
-        hop.exception_cannot_occur()
-        c_why = hop.inputconst(lltype.Signed, 42)    # XXX
-        hop.genop("stm_become_inevitable", [c_why])
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
@@ -747,10 +747,16 @@
 {
   struct tx_descriptor *d = thread_descriptor;
   if (d == NULL)
-    return -1;
+    return -2;
   if (active_thread_descriptor == NULL)
-    return 0;
+    {
+      if (d->my_lock_word == 0)
+        return -1;
+      else
+        return 0;
+    }
   assert(d == active_thread_descriptor);
+  assert(d->my_lock_word != 0);
   if (!is_inevitable(d))
     return 1;
   else
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
@@ -1,14 +1,45 @@
-from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.memory.gc.stmgc import PRIMITIVE_SIZES, GETSIZE, CALLBACK
-from pypy.translator.stm import _rffi_stm
+import py
+from pypy.tool.autopath import pypydir
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rlib.rarithmetic import LONG_BIT
 
 
+cdir = py.path.local(pypydir) / 'translator' / 'stm'
+cdir2 = py.path.local(pypydir) / 'translator' / 'c'
+
+eci = ExternalCompilationInfo(
+    include_dirs = [cdir, cdir2],
+    includes = ['src_stm/et.h', 'src_stm/et.c'],
+    pre_include_bits = ['#define PYPY_LONG_BIT %d' % LONG_BIT],
+    separate_module_sources = ['\n'],    # hack for test_rffi_stm
+)
+
+def _llexternal(name, args, result, **kwds):
+    return rffi.llexternal(name, args, result, compilation_info=eci,
+                           _nowrapper=True, **kwds)
+
 def smexternal(name, args, result):
-    return staticmethod(_rffi_stm.llexternal(name, args, result))
+    return staticmethod(_llexternal(name, args, result))
+
+# ____________________________________________________________
 
 
 class StmOperations(object):
 
+    PRIMITIVE_SIZES   = {1: lltype.Char,
+                         2: rffi.SHORT,
+                         4: rffi.INT,
+                         8: lltype.SignedLongLong,
+                         '8f': rffi.DOUBLE,
+                         '4f': rffi.FLOAT}
+
+    CALLBACK_TX   = lltype.Ptr(lltype.FuncType([rffi.VOIDP, lltype.Signed],
+                                               rffi.VOIDP))
+    CALLBACK_ENUM = lltype.Ptr(lltype.FuncType([llmemory.Address] * 3,
+                                               lltype.Void))
+    GETSIZE  = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
+
     def _freeze_(self):
         return True
 
@@ -28,7 +59,7 @@
                                llmemory.Address)
     tldict_add = smexternal('stm_tldict_add', [llmemory.Address] * 2,
                             lltype.Void)
-    tldict_enum = smexternal('stm_tldict_enum', [CALLBACK], lltype.Void)
+    tldict_enum = smexternal('stm_tldict_enum', [CALLBACK_ENUM], lltype.Void)
 
     for _size, _TYPE in PRIMITIVE_SIZES.items():
         _name = 'stm_read_int%s' % _size
@@ -40,3 +71,16 @@
                                                 llmemory.Address,
                                                 lltype.Signed],
                                                lltype.Void)
+
+    try_inevitable = smexternal('stm_try_inevitable', [], lltype.Void)
+    perform_transaction = smexternal('stm_perform_transaction',
+                                     [CALLBACK_TX, rffi.VOIDP], rffi.VOIDP)
+    thread_id        = smexternal('stm_thread_id',       [], lltype.Signed)
+    abort_and_retry  = smexternal('stm_abort_and_retry', [], lltype.Void)
+
+    _debug_get_state = smexternal('stm_debug_get_state', [], lltype.Signed)
+    STATE_NOT_INITIALIZED   = -2
+    STATE_MAIN_THREAD       = -1
+    STATE_INACTIVE          = 0
+    STATE_ACTIVE            = 1
+    STATE_ACTIVE_INEVITABLE = 2
diff --git a/pypy/translator/stm/test/support.py b/pypy/translator/stm/test/support.py
--- a/pypy/translator/stm/test/support.py
+++ b/pypy/translator/stm/test/support.py
@@ -4,7 +4,7 @@
 
 
 class CompiledSTMTests(StandaloneTests):
-    gc = "none"
+    gc = "stmgc"
 
     def compile(self, entry_point):
         from pypy.config.pypyoption import get_pypy_config
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
@@ -2,65 +2,10 @@
 from pypy.rlib.rarithmetic import r_longlong, r_singlefloat
 from pypy.rlib.objectmodel import compute_identity_hash
 from pypy.translator.stm.test.support import CompiledSTMTests
-from pypy.translator.stm._rffi_stm import (CALLBACK, stm_perform_transaction,
-                                           stm_descriptor_init, stm_descriptor_done)
-from pypy.translator.c.test.test_standalone import StandaloneTests
 from pypy.rlib.debug import debug_print
 from pypy.rpython.annlowlevel import llhelper
 
 
-class TestRStm(object):
-
-    def compile(self, entry_point):
-        from pypy.translator.translator import TranslationContext
-        from pypy.annotation.listdef import s_list_of_strings
-        from pypy.translator.c.genc import CStandaloneBuilder
-        from pypy.translator.tool.cbuild import ExternalCompilationInfo
-        t = TranslationContext()
-        t.config.translation.gc = 'boehm'
-        t.buildannotator().build_types(entry_point, [s_list_of_strings])
-        t.buildrtyper().specialize()
-        t.stm_transformation_applied = True   # not really, but for these tests
-        cbuilder = CStandaloneBuilder(t, entry_point, t.config)
-        force_debug = ExternalCompilationInfo(pre_include_bits=[
-            "#define RPY_ASSERT 1\n"
-            "#define RPY_LL_ASSERT 1\n"
-            ])
-        cbuilder.eci = cbuilder.eci.merge(force_debug)
-        cbuilder.generate_source()
-        cbuilder.compile()
-        return t, cbuilder
-
-    def test_compiled_stm_getfield(self):
-        from pypy.translator.stm.test import test_llstm
-        def entry_point(argv):
-            test_llstm.test_stm_getfield()
-            debug_print('ok!')
-            return 0
-        t, cbuilder = self.compile(entry_point)
-        _, data = cbuilder.cmdexec('', err=True)
-        assert data.endswith('ok!\n')
-
-    def test_compiled_stm_setfield(self):
-        from pypy.translator.stm.test import test_llstm
-        def entry_point(argv):
-            test_llstm.test_stm_setfield()
-            debug_print('ok!')
-            return 0
-        t, cbuilder = self.compile(entry_point)
-        _, data = cbuilder.cmdexec('', err=True)
-        assert data.endswith('ok!\n')
-
-    def test_compile_identity_hash(self):
-        class A:
-            pass
-        def entry_point(argv):
-            a = A()
-            debug_print(compute_identity_hash(a))
-            return 0
-        t, cbuilder = self.compile(entry_point)
-        _, data = cbuilder.cmdexec('', err=True)
-
 # ____________________________________________________________
 
 A = lltype.GcStruct('A', ('x', lltype.Signed), ('y', lltype.Signed),
diff --git a/pypy/translator/stm/test/test_rffi_stm.py b/pypy/translator/stm/test/test_rffi_stm.py
deleted file mode 100644
--- a/pypy/translator/stm/test/test_rffi_stm.py
+++ /dev/null
@@ -1,77 +0,0 @@
-from pypy.translator.stm._rffi_stm import *
-from pypy.rpython.annlowlevel import llhelper
-
-def test_descriptor():
-    stm_descriptor_init()
-    stm_descriptor_done()
-
-def test_stm_perform_transaction():
-    def callback1(x, retry_counter):
-        return lltype.nullptr(rffi.VOIDP.TO)
-    stm_descriptor_init()
-    stm_perform_transaction(llhelper(CALLBACK, callback1),
-                        lltype.nullptr(rffi.VOIDP.TO))
-    stm_descriptor_done()
-
-def test_stm_abort_and_retry():
-    A = lltype.Struct('A', ('x', lltype.Signed), ('y', lltype.Signed))
-    a = lltype.malloc(A, immortal=True, flavor='raw')
-    a.y = 0
-    def callback1(x, retry_counter):
-        assert retry_counter == a.y
-        if a.y < 10:
-            a.y += 1    # non-transactionally
-            stm_abort_and_retry()
-        else:
-            a.x = 42 * a.y
-            return lltype.nullptr(rffi.VOIDP.TO)
-    stm_descriptor_init()
-    stm_perform_transaction(llhelper(CALLBACK, callback1),
-                        lltype.nullptr(rffi.VOIDP.TO))
-    stm_descriptor_done()
-    assert a.x == 420
-
-def test_stm_abort_and_retry_transactionally():
-    A = lltype.Struct('A', ('x', lltype.Signed), ('y', lltype.Signed))
-    a = lltype.malloc(A, immortal=True, flavor='raw')
-    a.x = -611
-    a.y = 0
-    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)
-        assert rffi.cast(lltype.Signed, stm_read_word(p)) == -611
-        stm_write_word(p, 42 * a.y)
-        assert rffi.cast(lltype.Signed, stm_read_word(p)) == 42 * a.y
-        assert a.x == -611 # xxx still the old value when reading non-transact.
-        if a.y < 10:
-            a.y += 1    # non-transactionally
-            stm_abort_and_retry()
-        else:
-            return lltype.nullptr(rffi.VOIDP.TO)
-    stm_descriptor_init()
-    stm_perform_transaction(llhelper(CALLBACK, callback1),
-                            lltype.nullptr(rffi.VOIDP.TO))
-    stm_descriptor_done()
-    assert a.x == 420
-
-def test_stm_debug_get_state():
-    def callback1(x, retry_counter):
-        assert stm_debug_get_state() == 1
-        stm_try_inevitable()
-        assert stm_debug_get_state() == 2
-        return lltype.nullptr(rffi.VOIDP.TO)
-    assert stm_debug_get_state() == -1
-    stm_descriptor_init()
-    assert stm_debug_get_state() == 0
-    stm_perform_transaction(llhelper(CALLBACK, callback1),
-                            lltype.nullptr(rffi.VOIDP.TO))
-    stm_descriptor_done()
-
-def test_stm_thread_id():
-    assert stm_thread_id() == 0
-    stm_descriptor_init()
-    assert stm_thread_id() != 0
-    stm_descriptor_done()
-    assert stm_thread_id() == 0
diff --git a/pypy/translator/stm/test/test_stmgcintf.py b/pypy/translator/stm/test/test_stmgcintf.py
--- a/pypy/translator/stm/test/test_stmgcintf.py
+++ b/pypy/translator/stm/test/test_stmgcintf.py
@@ -1,7 +1,7 @@
-import random
+import py, random
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.annlowlevel import llhelper
-from pypy.translator.stm.stmgcintf import StmOperations, CALLBACK, GETSIZE
+from pypy.translator.stm.stmgcintf import StmOperations
 from pypy.rpython.memory.gc import stmgc
 
 WORD = stmgc.WORD
@@ -84,16 +84,16 @@
                 content[key] = a2
     test_tldict_large.in_transaction = True
 
-    def get_callback(self):
+    def get_callback_enum(self):
         def callback(tls, key, value):
             assert tls == llmemory.cast_ptr_to_adr(self.tls)
             seen.append((key, value))
         seen = []
-        p_callback = llhelper(CALLBACK, callback)
+        p_callback = llhelper(StmOperations.CALLBACK_ENUM, callback)
         return p_callback, seen
 
     def test_enum_tldict_empty(self):
-        p_callback, seen = self.get_callback()
+        p_callback, seen = self.get_callback_enum()
         stm_operations.tldict_enum(p_callback)
         assert seen == []
 
@@ -105,7 +105,7 @@
         #
         stm_operations.tldict_add(a1, a2)
         stm_operations.tldict_add(a3, a4)
-        p_callback, seen = self.get_callback()
+        p_callback, seen = self.get_callback_enum()
         stm_operations.tldict_enum(p_callback)
         assert (seen == [(a1, a2), (a3, a4)] or
                 seen == [(a3, a4), (a1, a2)])
@@ -169,13 +169,13 @@
         assert r1 == A and r2 == B and r3 == C
 
     def test_stm_read_int(self):
-        for size, TYPE in stmgc.PRIMITIVE_SIZES.items():
+        for size, TYPE in StmOperations.PRIMITIVE_SIZES.items():
             yield self.stm_read_intX, TYPE, size
 
     def test_stm_size_getter(self):
         def getsize(addr):
             dont_call_me
-        getter = llhelper(GETSIZE, getsize)
+        getter = llhelper(StmOperations.GETSIZE, getsize)
         stm_operations.setup_size_getter(getter)
         # ^^^ just tests that the function is really defined
 
@@ -215,3 +215,73 @@
     def test_not_in_transaction_main(self):
         assert not stm_operations.in_transaction()
     test_not_in_transaction.in_main_thread = True
+
+    def test_stm_perform_transaction(self):
+        def callback1(x, retry_counter):
+            return rffi.cast(rffi.VOIDP, -123)
+        x = stm_operations.perform_transaction(
+            llhelper(StmOperations.CALLBACK_TX, callback1),
+            lltype.nullptr(rffi.VOIDP.TO))
+        assert x == rffi.cast(rffi.VOIDP, -123)
+
+    def test_stm_try_inevitable(self):
+        # not really testing anything more than the presence of the function
+        stm_operations.try_inevitable()
+    test_stm_try_inevitable.in_transaction = True
+
+    def test_thread_id_main(self):
+        assert stm_operations.thread_id() == 0
+    test_thread_id_main.in_main_thread = True
+
+    def test_thread_id_nonmain(self):
+        assert stm_operations.thread_id() != 0
+    test_thread_id_nonmain.in_main_thread = False
+
+    def test_abort_and_retry(self):
+        def callback1(x, retry_counter):
+            assert 0 <= retry_counter <= 10
+            if retry_counter == 10:
+                return rffi.cast(rffi.VOIDP, -42)
+            stm_operations.abort_and_retry()
+            assert 0   # not reachable
+        x = stm_operations.perform_transaction(
+            llhelper(StmOperations.CALLBACK_TX, callback1),
+            lltype.nullptr(rffi.VOIDP.TO))
+        assert x == rffi.cast(rffi.VOIDP, -42)
+
+    def test_debug_get_state_main_thread(self):
+        st = stm_operations._debug_get_state()
+        assert st == stm_operations.STATE_MAIN_THREAD
+    test_debug_get_state_main_thread.in_main_thread = True
+
+    def test_debug_get_state_inactive(self):
+        st = stm_operations._debug_get_state()
+        assert st == stm_operations.STATE_INACTIVE
+    test_debug_get_state_inactive.in_main_thread = False
+
+    def test_debug_get_state_active(self):
+        def callback1(x, retry_counter):
+            st = stm_operations._debug_get_state()
+            return rffi.cast(rffi.VOIDP, st)
+        x = stm_operations.perform_transaction(
+            llhelper(StmOperations.CALLBACK_TX, callback1),
+            lltype.nullptr(rffi.VOIDP.TO))
+        assert rffi.cast(lltype.Signed, x) == stm_operations.STATE_ACTIVE
+    test_debug_get_state_active.in_main_thread = False
+
+    def test_debug_get_state_active_inevitable(self):
+        def callback1(x, retry_counter):
+            stm_operations.try_inevitable()
+            st = stm_operations._debug_get_state()
+            return rffi.cast(rffi.VOIDP, st)
+        x = stm_operations.perform_transaction(
+            llhelper(StmOperations.CALLBACK_TX, callback1),
+            lltype.nullptr(rffi.VOIDP.TO))
+        assert (rffi.cast(lltype.Signed, x) ==
+                stm_operations.STATE_ACTIVE_INEVITABLE)
+    test_debug_get_state_active_inevitable.in_main_thread = False
+
+
+def test_debug_get_state_not_initialized():
+    st = stm_operations._debug_get_state()
+    assert st == stm_operations.STATE_NOT_INITIALIZED
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -1,7 +1,6 @@
 from pypy.objspace.flow.model import SpaceOperation, Constant, Variable
 from pypy.objspace.flow.model import Block, Link, checkgraph
 from pypy.annotation import model as annmodel
-from pypy.translator.stm import _rffi_stm
 from pypy.translator.unsimplify import varoftype, copyvar
 from pypy.rpython.lltypesystem import lltype, lloperation
 from pypy.rpython import rclass


More information about the pypy-commit mailing list