Author: Armin Rigo <[email protected]>
Branch: stm-gc
Changeset: r54632:73a511a0a3df
Date: 2012-04-22 22:00 +0200
http://bitbucket.org/pypy/pypy/changeset/73a511a0a3df/

Log:    Start porting these tests as C code.

diff --git a/pypy/translator/stm/test/getlib.py 
b/pypy/translator/stm/test/getlib.py
deleted file mode 100644
--- a/pypy/translator/stm/test/getlib.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.translator.stm.stmgcintf import eci
-
-
-src_code = r'''
-
-struct pypy_header0 {
-    long h_tid;
-    void *h_version;
-};
-
-struct pypy_pypy_rlib_rstm_Transaction0 {
-    struct pypy_header0 header;
-    struct pypy_pypy_rlib_rstm_Transaction0 *t_inst__next_transaction;
-};
-
-
-#include "src_stm/et.h"
-#include "src_stm/et.c"
-
-
-void (*stm_thread_starting)(void);
-void (*stm_thread_stopping)(void);
-void *(*stm_run_transaction)(void *, long);
-long (*stm_getsize)(void *);
-void (*stm_enum_callback)(void *, void *, void *);
-
-
-void pypy_g__stm_thread_starting(void) {
-    stm_thread_starting();
-}
-void pypy_g__stm_thread_stopping(void) {
-    stm_thread_stopping();
-}
-void *pypy_g__stm_run_transaction(void *a, long b) {
-    return stm_run_transaction(a, b);
-}
-long pypy_g__stm_getsize(void *a) {
-    return stm_getsize(a);
-}
-void pypy_g__stm_enum_callback(void *a, void *b, void *c) {
-    stm_enum_callback(a, b, c);
-}
-'''
-
-
-assert not hasattr(eci, '_with_ctypes')
-
-eci._with_ctypes = eci.merge(ExternalCompilationInfo(
-    separate_module_sources = [src_code],
-    ))
diff --git a/pypy/translator/stm/test/test_stmgcintf.c 
b/pypy/translator/stm/test/test_stmgcintf.c
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/test/test_stmgcintf.c
@@ -0,0 +1,130 @@
+
+#define PYPY_LONG_BIT   (sizeof(long) * 8)
+
+struct pypy_header0 {
+    long h_tid;
+    void *h_version;
+};
+
+struct pypy_pypy_rlib_rstm_Transaction0 {
+    struct pypy_header0 header;
+    struct pypy_pypy_rlib_rstm_Transaction0 *t_inst__next_transaction;
+    int foobar;
+    void (*callback)(void);
+};
+
+typedef char bool_t;
+
+
+#include "src_stm/et.h"
+#include "src_stm/et.c"
+
+
+void *(*cb_run_transaction)(void *, long);
+long (*cb_getsize)(void *);
+void (*cb_enum_callback)(void *, void *, void *);
+
+int _thread_started = 0;
+
+
+void pypy_g__stm_thread_starting(void) {
+    assert(_thread_started == 0);
+    _thread_started = 1;
+    stm_set_tls((void *)742, 0);
+}
+void pypy_g__stm_thread_stopping(void) {
+    assert(_thread_started == 1);
+    _thread_started = 0;
+    stm_del_tls();
+}
+void *pypy_g__stm_run_transaction(void *a, long b) {
+    assert(cb_run_transaction != NULL);
+    return cb_run_transaction(a, b);
+}
+long pypy_g__stm_getsize(void *a) {
+    assert(cb_getsize != NULL);
+    return cb_getsize(a);
+}
+void pypy_g__stm_enum_callback(void *a, void *b, void *c) {
+    assert(cb_enum_callback != NULL);
+    cb_enum_callback(a, b, c);
+}
+
+
+void test_set_get_del(void)
+{
+    stm_set_tls((void *)42, 1);
+    assert(stm_get_tls() == (void *)42);
+    stm_del_tls();
+}
+
+void *rt1(void *t1, long retry_counter)
+{
+    struct pypy_pypy_rlib_rstm_Transaction0 *t = t1;
+    assert(retry_counter == 0);
+    assert(t->foobar == 42);
+    t->foobar = 143;
+    return NULL;
+}
+void test_run_all_transactions(void)
+{
+    struct pypy_pypy_rlib_rstm_Transaction0 t;
+    t.foobar = 42;
+    cb_run_transaction = rt1;
+    stm_run_all_transactions(&t, 1);
+    assert(t.foobar == 143);
+}
+
+void *rt2(void *t1, long retry_counter)
+{
+    struct pypy_pypy_rlib_rstm_Transaction0 *t = t1;
+    if (retry_counter > 0) {
+        t->foobar = retry_counter;
+        return NULL;
+    }
+    t->callback();
+    t->foobar = 81;
+    return NULL;
+}
+void run_in_transaction(void(*cb)(void), int expected)
+{
+    struct pypy_pypy_rlib_rstm_Transaction0 t;
+    t.callback = cb;
+    cb_run_transaction = rt2;
+    stm_run_all_transactions(&t, 1);
+    assert(t.foobar == expected);
+}
+
+void tldict(void)
+{
+    void *a1 = (void *)0x4020;
+    void *a2 = (void *)10002;
+    void *a3 = (void *)0x4028;
+    void *a4 = (void *)10004;
+
+    assert(stm_tldict_lookup(a1) == NULL);
+    stm_tldict_add(a1, a2);
+    assert(stm_tldict_lookup(a1) == a2);
+
+    assert (stm_tldict_lookup(a3) == NULL);
+    stm_tldict_add(a3, a4);
+    assert(stm_tldict_lookup(a3) == a4);
+    assert(stm_tldict_lookup(a1) == a2);
+    stm_abort_and_retry();
+}
+void test_tldict(void)
+{
+    run_in_transaction(tldict, 1);
+}
+
+
+#define XTEST(name)  if (!strcmp(argv[1], #name)) { test_##name(); return 0; }
+
+int main(int argc, char **argv)
+{
+    XTEST(set_get_del);
+    XTEST(run_all_transactions);
+    XTEST(tldict);
+    printf("bad test name\n");
+    return 1;
+}
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,288 +1,20 @@
-import py, random
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi
-from pypy.rpython.annlowlevel import llhelper
-from pypy.translator.stm.stmgcintf import StmOperations
-from pypy.translator.stm.test import getlib    # for the side-effects
-from pypy.rpython.memory.gc import stmgc
+import os
+from pypy.tool.udir import udir
 
-WORD = stmgc.WORD
 
-stm_operations = StmOperations()
+def test_all():
+    executable = str(udir.join('test_stmgcintf'))
+    exitcode = os.system("gcc -g -o '%s' -pthread -I.. test_stmgcintf.c" % (
+        executable,))
+    assert exitcode == 0
+    #
+    for line in open('test_stmgcintf.c'):
+        line = line.strip()
+        if line.startswith('XTEST('):
+            assert line.endswith(');')
+            yield run_one_test, executable, line[6:-2]
 
-DEFAULT_TLS = lltype.Struct('DEFAULT_TLS')
 
-S1 = lltype.Struct('S1', ('hdr', stmgc.StmGC.HDR),
-                         ('x', lltype.Signed),
-                         ('y', lltype.Signed))
-
-# xxx a lot of casts to convince rffi to give us a regular integer :-(
-SIZEOFHDR = rffi.cast(lltype.Signed, rffi.cast(rffi.SHORT,
-                                               rffi.sizeof(S1.hdr)))
-
-
-def test_set_get_del():
-    # assume that they are really thread-local; not checked here
-    s = lltype.malloc(lltype.Struct('S'), flavor='raw')
-    a = llmemory.cast_ptr_to_adr(s)
-    stm_operations.set_tls(a, 1)
-    assert stm_operations.get_tls() == a
-    stm_operations.del_tls()
-    lltype.free(s, flavor='raw')
-
-
-class TestStmGcIntf:
-    _in_transaction = False
-
-    def setup_method(self, meth):
-        TLS = getattr(meth, 'TLS', DEFAULT_TLS)
-        s = lltype.malloc(TLS, flavor='raw', immortal=True)
-        self.tls = s
-        a = llmemory.cast_ptr_to_adr(s)
-        in_transaction = getattr(meth, 'in_transaction', False)
-        in_main_thread = getattr(meth, 'in_main_thread', not in_transaction)
-        stm_operations.set_tls(a, int(in_main_thread))
-        if in_transaction:
-            stm_operations._activate_transaction(1)
-            self._in_transaction = True
-
-    def teardown_method(self, meth):
-        if self._in_transaction:
-            stm_operations._activate_transaction(0)
-        stm_operations.del_tls()
-
-    def test_set_get_del(self):
-        a = llmemory.cast_ptr_to_adr(self.tls)
-        assert stm_operations.get_tls() == a
-
-    def test_tldict(self):
-        a1 = rffi.cast(llmemory.Address, 0x4020)
-        a2 = rffi.cast(llmemory.Address, 10002)
-        a3 = rffi.cast(llmemory.Address, 0x4028)
-        a4 = rffi.cast(llmemory.Address, 10004)
-        #
-        assert stm_operations.tldict_lookup(a1) == llmemory.NULL
-        stm_operations.tldict_add(a1, a2)
-        assert stm_operations.tldict_lookup(a1) == a2
-        #
-        assert stm_operations.tldict_lookup(a3) == llmemory.NULL
-        stm_operations.tldict_add(a3, a4)
-        assert stm_operations.tldict_lookup(a3) == a4
-        assert stm_operations.tldict_lookup(a1) == a2
-    test_tldict.in_transaction = True
-
-    def test_tldict_large(self):
-        content = {}
-        for i in range(12000):
-            key = random.randrange(1000, 2000) * WORD
-            a1 = rffi.cast(llmemory.Address, key)
-            a2 = stm_operations.tldict_lookup(a1)
-            if key in content:
-                assert a2 == content[key]
-            else:
-                assert a2 == llmemory.NULL
-                a2 = rffi.cast(llmemory.Address, random.randrange(2000, 9999))
-                stm_operations.tldict_add(a1, a2)
-                content[key] = a2
-    test_tldict_large.in_transaction = True
-
-    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(StmOperations.CALLBACK_ENUM, callback)
-        return p_callback, seen
-
-    def test_enum_tldict_empty(self):
-        p_callback, seen = self.get_callback_enum()
-        stm_operations.tldict_enum(p_callback)
-        assert seen == []
-
-    def test_enum_tldict_nonempty(self):
-        a1 = rffi.cast(llmemory.Address, 0x4020)
-        a2 = rffi.cast(llmemory.Address, 10002)
-        a3 = rffi.cast(llmemory.Address, 0x4028)
-        a4 = rffi.cast(llmemory.Address, 10004)
-        #
-        stm_operations.tldict_add(a1, a2)
-        stm_operations.tldict_add(a3, a4)
-        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)])
-    test_enum_tldict_nonempty.in_transaction = True
-
-    def stm_read_case(self, flags, copied=False):
-        # doesn't test STM behavior, but just that it appears to work
-        s1 = lltype.malloc(S1, flavor='raw')
-        s1.hdr.tid = stmgc.GCFLAG_GLOBAL | flags
-        s1.hdr.version = llmemory.NULL
-        s1.x = 42042
-        if copied:
-            s2 = lltype.malloc(S1, flavor='raw')
-            s2.hdr.tid = stmgc.GCFLAG_WAS_COPIED
-            s2.hdr.version = llmemory.NULL
-            s2.x = 84084
-            a1 = llmemory.cast_ptr_to_adr(s1)
-            a2 = llmemory.cast_ptr_to_adr(s2)
-            stm_operations.tldict_add(a1, a2)
-        reader = getattr(stm_operations, 'stm_read_int%d' % WORD)
-        res = reader(llmemory.cast_ptr_to_adr(s1), SIZEOFHDR)   # 'x'
-        lltype.free(s1, flavor='raw')
-        if copied:
-            lltype.free(s2, flavor='raw')
-        return res
-
-    def test_stm_read_word_main_thread(self):
-        res = self.stm_read_case(0)                        # not copied
-        assert res == 42042
-        res = self.stm_read_case(stmgc.GCFLAG_WAS_COPIED)  # but ignored
-        assert res == 42042
-
-    def test_stm_read_word_transactional_thread(self):
-        res = self.stm_read_case(0)                        # not copied
-        assert res == 42042
-        res = self.stm_read_case(stmgc.GCFLAG_WAS_COPIED)  # but ignored
-        assert res == 42042
-        res = self.stm_read_case(stmgc.GCFLAG_WAS_COPIED, copied=True)
-        assert res == 84084
-    test_stm_read_word_transactional_thread.in_transaction = True
-
-    def stm_read_intX(self, TYPE, sizesuffix):
-        print TYPE, sizesuffix
-        S2 = lltype.Struct('S2', ('hdr', stmgc.StmGC.HDR),
-                                 ('c1', TYPE),
-                                 ('c2', TYPE),
-                                 ('c3', TYPE))
-        s2 = lltype.malloc(S2, flavor='raw')
-        s2.hdr.tid = stmgc.GCFLAG_GLOBAL | stmgc.GCFLAG_WAS_COPIED
-        s2.hdr.version = llmemory.NULL
-        s2.c1 = A = rffi.cast(TYPE, -65)
-        s2.c2 = B = rffi.cast(TYPE, -66)
-        s2.c3 = C = rffi.cast(TYPE, -67)
-        size = rffi.sizeof(TYPE)
-        assert sizesuffix in (size, '%df' % size)
-        reader = getattr(stm_operations, 'stm_read_int%s' % sizesuffix)
-        r1 = reader(llmemory.cast_ptr_to_adr(s2), SIZEOFHDR + 0 * size)  # c1
-        r2 = reader(llmemory.cast_ptr_to_adr(s2), SIZEOFHDR + 1 * size)  # c2
-        r3 = reader(llmemory.cast_ptr_to_adr(s2), SIZEOFHDR + 2 * size)  # c3
-        lltype.free(s2, flavor='raw')
-        assert r1 == A and r2 == B and r3 == C
-
-    def test_stm_read_int(self):
-        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(StmOperations.GETSIZE, getsize)
-        stm_operations.setup_size_getter(getter)
-        # ^^^ just tests that the function is really defined
-
-    def test_stm_copy_transactional_to_raw(self):
-        # doesn't test STM behavior, but just that it appears to work
-        s1 = lltype.malloc(S1, flavor='raw')
-        s1.hdr.tid = stmgc.GCFLAG_GLOBAL
-        s1.hdr.version = llmemory.NULL
-        s1.x = 909
-        s1.y = 808
-        s2 = lltype.malloc(S1, flavor='raw')
-        s2.hdr.tid = -42    # non-initialized
-        s2.x = -42          # non-initialized
-        s2.y = -42          # non-initialized
-        #
-        s1_adr = llmemory.cast_ptr_to_adr(s1)
-        s2_adr = llmemory.cast_ptr_to_adr(s2)
-        size   = llmemory.sizeof(S1)
-        stm_operations.stm_copy_transactional_to_raw(s1_adr, s2_adr, size)
-        #
-        assert s2.hdr.tid == -42    # not touched
-        assert s2.x == 909
-        assert s2.y == 808
-        #
-        lltype.free(s2, flavor='raw')
-        lltype.free(s1, flavor='raw')
-    test_stm_copy_transactional_to_raw.in_transaction = True
-
-    def test_in_transaction(self):
-        assert stm_operations.in_transaction()
-    test_in_transaction.in_transaction = True
-
-    def test_not_in_transaction(self):
-        assert not stm_operations.in_transaction()
-    test_not_in_transaction.in_main_thread = False
-
-    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
+def run_one_test(executable, testname):
+    exitcode = os.system("'%s' %s" % (executable, testname))
+    assert exitcode == 0, "exitcode is %r running %r" % (exitcode, testname)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to