[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