[pypy-commit] pypy default: Support threadlocalref_{addr, get} when running on the llinterp too.

arigo noreply at buildbot.pypy.org
Fri Nov 28 14:57:43 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r74753:0331b21a1685
Date: 2014-11-28 14:51 +0100
http://bitbucket.org/pypy/pypy/changeset/0331b21a1685/

Log:	Support threadlocalref_{addr,get} when running on the llinterp too.

diff --git a/rpython/jit/metainterp/test/test_threadlocal.py b/rpython/jit/metainterp/test/test_threadlocal.py
--- a/rpython/jit/metainterp/test/test_threadlocal.py
+++ b/rpython/jit/metainterp/test/test_threadlocal.py
@@ -11,10 +11,11 @@
         tlfield = rthread.ThreadLocalField(lltype.Signed, 'foobar_test_')
 
         def f():
+            tlfield.setraw(0x544c)
             return tlfield.getraw()
 
         res = self.interp_operations(f, [])
-        assert res == 0x544c    # magic value returned by llinterp
+        assert res == 0x544c
 
 
 class TestLLtype(ThreadLocalTest, LLJitMixin):
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -286,11 +286,13 @@
             _threadlocalref_seeme(self)
             return llop.threadlocalref_get(FIELDTYPE, offset)
 
+        @jit.dont_look_inside
         def get_or_make_raw():
             _threadlocalref_seeme(self)
             addr = llop.threadlocalref_addr(llmemory.Address)
             return llop.raw_load(FIELDTYPE, addr, offset)
 
+        @jit.dont_look_inside
         def setraw(value):
             _threadlocalref_seeme(self)
             addr = llop.threadlocalref_addr(llmemory.Address)
diff --git a/rpython/rlib/test/test_rthread.py b/rpython/rlib/test/test_rthread.py
--- a/rpython/rlib/test/test_rthread.py
+++ b/rpython/rlib/test/test_rthread.py
@@ -52,6 +52,18 @@
     assert get_ident() == thread.get_ident()
 
 
+def test_threadlocalref_on_llinterp():
+    from rpython.rtyper.test.test_llinterp import interpret
+    tlfield = ThreadLocalField(lltype.Signed, "rthread_test_")
+    #
+    def f():
+        x = tlfield.setraw(42)
+        return tlfield.getraw()
+    #
+    res = interpret(f, [])
+    assert res == 42
+
+
 class AbstractThreadTests(AbstractGCTestClass):
     use_threads = True
 
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -133,6 +133,19 @@
         for line in lines:
             log.traceback(line)
 
+    def get_tlobj(self):
+        try:
+            return self._tlobj
+        except AttributeError:
+            from rpython.rtyper.lltypesystem import rffi
+            PERRNO = rffi.CArrayPtr(rffi.INT)
+            fake_p_errno = lltype.malloc(PERRNO.TO, 1, flavor='raw', zero=True,
+                                         track_allocation=False)
+            self._tlobj = {'RPY_TLOFS_p_errno': fake_p_errno,
+                           #'thread_ident': ...,
+                           }
+            return self._tlobj
+
     def find_roots(self):
         """Return a list of the addresses of the roots."""
         #log.findroots("starting")
@@ -920,13 +933,11 @@
         return 0
 
     def op_threadlocalref_addr(self):
-        raise NotImplementedError("threadlocalref_addr")
+        return _address_of_thread_local()
 
-    def op_threadlocalref_get(self, offset):
-        if (type(offset) is CDefinedIntSymbolic and
-                offset.expr == 'RPY_TLOFS_foobar_test_'):   # used in tests
-            return 0x544c
-        raise NotImplementedError("threadlocalref_get")
+    def op_threadlocalref_get(self, RESTYPE, offset):
+        return self.op_raw_load(RESTYPE, _address_of_thread_local(), offset)
+    op_threadlocalref_get.need_result_type = True
 
     # __________________________________________________________
     # operations on addresses
@@ -973,9 +984,9 @@
             ll_p = rffi.cast(rffi.CArrayPtr(RESTYPE),
                              rffi.ptradd(ll_p, offset))
             value = ll_p[0]
-        ## elif getattr(addr, 'is_fake_thread_local_addr', False):
-        ##     assert type(offset) is CDefinedIntSymbolic
-        ##     value = self.llinterpreter.tlobj[offset.expr]
+        elif getattr(addr, 'is_fake_thread_local_addr', False):
+            assert type(offset) is CDefinedIntSymbolic
+            value = self.llinterpreter.get_tlobj()[offset.expr]
         else:
             assert offset.TYPE == RESTYPE
             value = getattr(addr, str(RESTYPE).lower())[offset.repeat]
@@ -996,9 +1007,9 @@
             ll_p = rffi.cast(rffi.CArrayPtr(ARGTYPE),
                              rffi.ptradd(ll_p, offset))
             ll_p[0] = value
-        ## elif getattr(addr, 'is_fake_thread_local_addr', False):
-        ##     assert type(offset) is CDefinedIntSymbolic
-        ##     self.llinterpreter.tlobj[offset.expr] = value
+        elif getattr(addr, 'is_fake_thread_local_addr', False):
+            assert type(offset) is CDefinedIntSymbolic
+            self.llinterpreter.get_tlobj()[offset.expr] = value
         else:
             assert offset.TYPE == ARGTYPE
             getattr(addr, str(ARGTYPE).lower())[offset.repeat] = value
@@ -1320,6 +1331,10 @@
             return llmemory.fakeaddress(addr.ptr._obj._ptr)
         return addr
 
+class _address_of_thread_local(object):
+    _TYPE = llmemory.Address
+    is_fake_thread_local_addr = True
+
 
 # by default we route all logging messages to nothingness
 # e.g. tests can then switch on logging to get more help


More information about the pypy-commit mailing list