Author: Armin Rigo <[email protected]>
Branch: stm-thread-2
Changeset: r61406:5d60f05ba873
Date: 2013-02-18 13:26 +0100
http://bitbucket.org/pypy/pypy/changeset/5d60f05ba873/
Log: Add the ThreadLocalReference class.
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -1,13 +1,15 @@
-import threading
+import thread
from rpython.translator.stm import stmgcintf
from rpython.rlib.debug import ll_assert, fatalerror
from rpython.rlib.objectmodel import keepalive_until_here, specialize
from rpython.rlib.objectmodel import we_are_translated
from rpython.rlib.rposix import get_errno, set_errno
+from rpython.rlib.rarithmetic import intmask
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass
from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.rtyper.annlowlevel import (cast_instance_to_base_ptr,
- llhelper)
+from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr, llhelper
+from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
+
def is_inevitable():
return we_are_translated() and stmgcintf.StmOperations.is_inevitable()
@@ -102,3 +104,35 @@
perform_transaction._transaction_break_ = True
#
return perform_transaction
+
+# ____________________________________________________________
+
+class ThreadLocalReference(object):
+
+ def __init__(self, Cls):
+ "NOT_RPYTHON: must be prebuilt"
+ self.Cls = Cls
+ self.unique_id = intmask(id(self))
+ self.local = thread._local()
+
+ def _freeze_(self):
+ return True
+
+ @specialize.arg(0)
+ def get(self):
+ if we_are_translated():
+ ptr = llop.stm_localref_get(llmemory.Address, self.unique_id)
+ ptr = rffi.cast(rclass.OBJECTPTR, ptr)
+ return cast_base_ptr_to_instance(self.Cls, ptr)
+ else:
+ return getattr(self.local, 'value', None)
+
+ @specialize.arg(0)
+ def set(self, value):
+ assert isinstance(value, self.Cls) or value is None
+ if we_are_translated():
+ ptr = cast_instance_to_base_ptr(value)
+ ptr = rffi.cast(llmemory.Address, ptr)
+ llop.stm_localref_set(lltype.Void, self.unique_id, ptr)
+ else:
+ self.local.value = value
diff --git a/rpython/rlib/test/test_rstm.py b/rpython/rlib/test/test_rstm.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/test/test_rstm.py
@@ -0,0 +1,17 @@
+import thread, time
+from rpython.rlib.rstm import ThreadLocalReference
+
+def test_tlref_untranslated():
+ class FooBar(object):
+ pass
+ t = ThreadLocalReference(FooBar)
+ results = []
+ def subthread():
+ x = FooBar()
+ t.set(x)
+ time.sleep(0.2)
+ results.append(t.get() is x)
+ for i in range(5):
+ thread.start_new_thread(subthread, ())
+ time.sleep(0.5)
+ assert results == [True] * 5
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit