Author: Armin Rigo <[email protected]>
Branch: stm
Changeset: r51491:fd78c427e13b
Date: 2012-01-19 17:51 +0100
http://bitbucket.org/pypy/pypy/changeset/fd78c427e13b/

Log:    (bivab, arigo)

        Fixed rlib.rstm to run correctly on top of CPython with multiple
        threads.

diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -1,3 +1,4 @@
+import thread
 from pypy.rlib.objectmodel import specialize, we_are_translated, 
keepalive_until_here
 from pypy.rpython.lltypesystem import rffi, lltype, rclass
 from pypy.rpython.annlowlevel import (cast_base_ptr_to_instance,
@@ -5,6 +6,8 @@
                                       llhelper)
 from pypy.translator.stm import _rffi_stm
 
+_global_lock = thread.allocate_lock()
+
 @specialize.memo()
 def _get_stm_callback(func, argcls):
     def _stm_callback(llarg):
@@ -26,14 +29,29 @@
         llarg = cast_instance_to_base_ptr(arg)
         llarg = rffi.cast(rffi.VOIDP, llarg)
     else:
-        # only for tests
+        # only for tests: we want (1) to test the calls to the C library,
+        # but also (2) to work with multiple Python threads, so we acquire
+        # and release some custom GIL here --- even though it doesn't make
+        # sense from an STM point of view :-/
+        _global_lock.acquire()
         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.stm_perform_transaction(llcallback, llarg)
     keepalive_until_here(arg)
+    if not we_are_translated():
+        _global_lock.release()
 
-descriptor_init = _rffi_stm.stm_descriptor_init
-descriptor_done = _rffi_stm.stm_descriptor_done
-debug_get_state = _rffi_stm.stm_debug_get_state
+def descriptor_init():
+    if not we_are_translated(): _global_lock.acquire()
+    _rffi_stm.stm_descriptor_init()
+    if not we_are_translated(): _global_lock.release()
+
+def descriptor_done():
+    if not we_are_translated(): _global_lock.acquire()
+    _rffi_stm.stm_descriptor_done()
+    if not we_are_translated(): _global_lock.release()
+
+def debug_get_state():
+    return _rffi_stm.stm_debug_get_state()
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
@@ -1,4 +1,4 @@
-import os
+import os, thread, time
 from pypy.rlib.debug import debug_print
 from pypy.rlib import rstm
 from pypy.translator.stm.test.support import CompiledSTMTests
@@ -29,6 +29,20 @@
     assert rstm.debug_get_state() == -1
     assert arg.x == 42
 
+def test_stm_multiple_threads():
+    ok = []
+    def f(i):
+        test_stm_perform_transaction()
+        ok.append(i)
+    for i in range(10):
+        thread.start_new_thread(f, (i,))
+    timeout = 10
+    while len(ok) < 10:
+        time.sleep(0.1)
+        timeout -= 0.1
+        assert timeout >= 0.0, "timeout!"
+    assert sorted(ok) == range(10)
+
 
 class TestTransformSingleThread(CompiledSTMTests):
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to