[pypy-commit] pypy portable-threadlocal: Found out that the jit works, but produces too much cruft in the traces.

arigo noreply at buildbot.pypy.org
Mon Nov 24 12:27:09 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: portable-threadlocal
Changeset: r74658:da917334290a
Date: 2014-11-24 12:26 +0100
http://bitbucket.org/pypy/pypy/changeset/da917334290a/

Log:	Found out that the jit works, but produces too much cruft in the
	traces. Change the llops a bit in the hope to improve the situation.
	(jit not fixed yet.)

diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -284,12 +284,11 @@
 
         def getraw():
             _threadlocalref_seeme(self)
-            addr = llop.threadlocalref_addr(llmemory.Address)
-            return llop.raw_load(FIELDTYPE, addr, offset)
+            return llop.threadlocalref_get(FIELDTYPE, offset)
 
         def get_or_make_raw():
             _threadlocalref_seeme(self)
-            addr = llop.threadlocalref_make(llmemory.Address)
+            addr = llop.threadlocalref_addr(llmemory.Address)
             return llop.raw_load(FIELDTYPE, addr, offset)
 
         def setraw(value):
@@ -316,15 +315,15 @@
         unique_id = ThreadLocalReference._COUNT
         ThreadLocalReference._COUNT += 1
         ThreadLocalField.__init__(self, lltype.Signed, 'tlref%d' % unique_id)
-        getraw = self.getraw
         setraw = self.setraw
+        offset = self.offset
 
         def get():
             if we_are_translated():
                 from rpython.rtyper.annlowlevel import cast_gcref_to_instance
-                value = getraw()
-                value = lltype.cast_int_to_ptr(llmemory.GCREF, value)
-                return cast_gcref_to_instance(Cls, value)
+                _threadlocalref_seeme(self)
+                gcref = llop.threadlocalref_get(llmemory.GCREF, offset)
+                return cast_gcref_to_instance(Cls, gcref)
             else:
                 return getattr(self.local, 'value', None)
 
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -546,8 +546,8 @@
     'getslice':             LLOp(canraise=(Exception,)),
     'check_and_clear_exc':  LLOp(),
 
-    'threadlocalref_addr':  LLOp(sideeffects=False),
-    'threadlocalref_make':  LLOp(),
+    'threadlocalref_addr':  LLOp(sideeffects=False),  # get (or make) addr of tl
+    'threadlocalref_get':   LLOp(sideeffects=False),  # read field (no check)
 
     # __________ debugging __________
     'debug_view':           LLOp(),
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -13,6 +13,7 @@
 from rpython.translator.backendopt.ssa import SSI_to_SSA
 from rpython.translator.backendopt.innerloop import find_inner_loops
 from rpython.tool.identity_dict import identity_dict
+from rpython.rlib.objectmodel import CDefinedIntSymbolic
 
 
 LOCALVAR = 'l_%s'
@@ -900,4 +901,16 @@
         else:
             return None    # use the default
 
+    def OP_THREADLOCALREF_GET(self, op):
+        assert isinstance(op.args[0], Constant)
+        assert isinstance(op.args[0].value, CDefinedIntSymbolic)
+        fieldname = op.args[0].value.expr
+        assert fieldname.startswith('RPY_TLOFS_')
+        fieldname = fieldname[10:]
+        typename = self.db.gettype(op.result.concretetype)
+        return '%s = (%s)RPY_THREADLOCALREF_GET(%s);' % (
+            self.expr(op.result),
+            cdecl(typename, ''),
+            fieldname)
+
 assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator)
diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py
--- a/rpython/translator/c/gc.py
+++ b/rpython/translator/c/gc.py
@@ -75,7 +75,7 @@
         # in all cases except with framework+shadowstack.  In that
         # case the operation is removed because redundant with
         # rthread.get_or_make_ident().
-        return '{ char *r; OP_THREADLOCALREF_MAKE(r); (void)r; } '
+        return 'RPY_THREADLOCALREF_ENSURE();'
 
     def OP_GC_THREAD_START(self, funcgen, op):
         return ''
diff --git a/rpython/translator/c/src/threadlocal.c b/rpython/translator/c/src/threadlocal.c
--- a/rpython/translator/c/src/threadlocal.c
+++ b/rpython/translator/c/src/threadlocal.c
@@ -69,12 +69,6 @@
    explicitly, with malloc()/free(), and attached to (a single) thread-
    local key using the API of Windows or pthread. */
 
-#ifdef _WIN32
-#  define _RPy_ThreadLocals_Set(p)  TlsSetValue(pypy_threadlocal_key, p)
-#else
-#  define _RPy_ThreadLocals_Set(p)  pthread_setspecific(pypy_threadlocal_key, p)
-#endif
-
 void RPython_ThreadLocals_ProgramInit(void)
 {
 #ifdef _WIN32
@@ -106,11 +100,12 @@
 
 void RPython_ThreadLocals_ThreadDie(void)
 {
-    void *p;
-    OP_THREADLOCALREF_ADDR(p);
-    _RPy_ThreadLocals_Set(NULL);
-    memset(p, 0xDD, sizeof(struct pypy_threadlocal_s));  /* debug */
-    free(p);
+    void *p = _RPy_ThreadLocals_Get();
+    if (p != NULL) {
+        _RPy_ThreadLocals_Set(NULL);
+        memset(p, 0xDD, sizeof(struct pypy_threadlocal_s));  /* debug */
+        free(p);
+    }
 }
 
 
diff --git a/rpython/translator/c/src/threadlocal.h b/rpython/translator/c/src/threadlocal.h
--- a/rpython/translator/c/src/threadlocal.h
+++ b/rpython/translator/c/src/threadlocal.h
@@ -31,35 +31,18 @@
 
 RPY_EXTERN __thread struct pypy_threadlocal_s pypy_threadlocal;
 
-#define OP_THREADLOCALREF_ADDR(r)                       \
-    do {                                                \
-        RPyAssert(pypy_threadlocal.ready == 42,         \
-                  "uninitialized thread-local!");       \
-        r = (char *)&pypy_threadlocal;                  \
-    } while (0)
-
-#define OP_THREADLOCALREF_MAKE(r)               \
+#define OP_THREADLOCALREF_ADDR(r)               \
     do {                                        \
         r = (char *)&pypy_threadlocal;          \
         if (pypy_threadlocal.ready != 42)       \
             r = _RPython_ThreadLocals_Build();  \
     } while (0)
 
+#define RPY_THREADLOCALREF_ENSURE()             \
+    if (pypy_threadlocal.ready != 42)           \
+        (void)_RPython_ThreadLocals_Build();
 
-/* ------------------------------------------------------------ */
-#elif _WIN32
-/* ------------------------------------------------------------ */
-
-
-#include <WinSock2.h>
-#include <windows.h>
-
-RPY_EXTERN DWORD pypy_threadlocal_key;
-#define OP_THREADLOCALREF_ADDR(r)    r = (char *)TlsGetValue(  \
-                                           pypy_threadlocal_key)
-#define OP_THREADLOCALREF_MAKE(r)                       \
-    (OP_THREADLOCALREF_ADDR(r),                         \
-     ((r) || (r = _RPython_ThreadLocals_Build())))
+#define RPY_THREADLOCALREF_GET(FIELD)   pypy_threadlocal.FIELD
 
 
 /* ------------------------------------------------------------ */
@@ -67,16 +50,35 @@
 /* ------------------------------------------------------------ */
 
 
-/* Other POSIX systems: use the pthread API */
+/* Don't use '__thread'. */
 
-#include <pthread.h>
+#ifdef _WIN32
+#  include <WinSock2.h>
+#  include <windows.h>
+#  define _RPy_ThreadLocals_Get  TlsGetValue
+#  define _RPy_ThreadLocals_Set  TlsSetValue
+RPY_EXTERN DWORD pypy_threadlocal_key;
+#else
+#  include <pthread.h>
+#  define _RPy_ThreadLocals_Get  pthread_getspecific
+#  define _RPy_ThreadLocals_Set  pthread_setspecific
+RPY_EXTERN pthread_key_t pypy_threadlocal_key;
+#endif
 
-RPY_EXTERN pthread_key_t pypy_threadlocal_key;
-#define OP_THREADLOCALREF_ADDR(r)    r = (char *)pthread_getspecific(  \
-                                           pypy_threadlocal_key)
-#define OP_THREADLOCALREF_MAKE(r)                       \
-    (OP_THREADLOCALREF_ADDR(r),                         \
-     ((r) || (r = _RPython_ThreadLocals_Build())))
+
+#define OP_THREADLOCALREF_ADDR(r)               \
+    do {                                        \
+        r = (char *)_RPy_ThreadLocals_Get();    \
+        if (!r)                                 \
+            r = _RPython_ThreadLocals_Build();  \
+    } while (0)
+
+#define RPY_THREADLOCALREF_ENSURE()             \
+    if (!_RPy_ThreadLocals_Get())               \
+        (void)_RPython_ThreadLocals_Build();
+
+#define RPY_THREADLOCALREF_GET(FIELD)           \
+    ((struct pypy_threadlocal_s *)_RPy_ThreadLocals_Get())->FIELD
 
 
 /* ------------------------------------------------------------ */


More information about the pypy-commit mailing list