[pypy-commit] pypy reverse-debugger: Hopefully correct handling of thread-locals
arigo
pypy.commits at gmail.com
Thu Aug 11 13:58:04 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r86158:0981c3747dd3
Date: 2016-08-11 19:57 +0200
http://bitbucket.org/pypy/pypy/changeset/0981c3747dd3/
Log: Hopefully correct handling of thread-locals
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -778,6 +778,10 @@
for field in fields:
print >> f, ('#define RPY_TLOFS_%s offsetof(' % field.fieldname +
'struct pypy_threadlocal_s, %s)' % field.fieldname)
+ if fields:
+ print >> f, '#define RPY_TLOFSFIRST RPY_TLOFS_%s' % fields[0].fieldname
+ else:
+ print >> f, '#define RPY_TLOFSFIRST sizeof(struct pypy_threadlocal_s)'
print >> f, 'struct pypy_threadlocal_s {'
print >> f, '\tint ready;'
print >> f, '\tchar *stack_end;'
diff --git a/rpython/translator/revdb/src-revdb/revdb.c b/rpython/translator/revdb/src-revdb/revdb.c
--- a/rpython/translator/revdb/src-revdb/revdb.c
+++ b/rpython/translator/revdb/src-revdb/revdb.c
@@ -26,6 +26,7 @@
#include "revdb_def.h"
#include "src/rtyper.h"
#include "src/mem.h"
+#include "src/threadlocal.h"
#include "src-revdb/revdb_include.h"
#define RDB_SIGNATURE "RevDB:"
@@ -673,6 +674,7 @@
struct replay_thread_s {
uint64_t tid;
stacklet_handle h;
+ struct pypy_threadlocal_s tloc;
};
static stacklet_handle replay_thread_main(stacklet_handle h, void *arg)
@@ -737,6 +739,7 @@
can switch it away at any point later */
struct replay_thread_main_s m;
stacklet_handle h;
+ struct pypy_threadlocal_s *real_tloc = NULL;
m.entry_point = entry_point;
m.argc = argc;
m.argv = argv;
@@ -750,6 +753,10 @@
while (1) {
struct replay_thread_s *node, **item, dummy;
+ if (real_tloc == NULL) {
+ _OP_THREADLOCALREF_ADDR_SIGHANDLER(real_tloc);
+ }
+
if (h == NULL)
goto out_of_memory;
@@ -761,6 +768,12 @@
goto out_of_memory;
node->tid = current_thread_id;
node->h = h;
+ /* save the thread-locals, if any */
+ if (real_tloc != NULL)
+ node->tloc = *real_tloc;
+ else
+ memset(&node->tloc, 0, sizeof(node->tloc));
+
item = tsearch(node, &thread_tree_root, compare_replay_thread);
if (item == NULL)
goto out_of_memory;
@@ -780,6 +793,9 @@
item = tfind(&dummy, &thread_tree_root, compare_replay_thread);
if (item == NULL) {
/* it's a new thread, start it now */
+ if (real_tloc != NULL)
+ memset(((char *)real_tloc) + RPY_TLOFSFIRST, 0,
+ sizeof(struct pypy_threadlocal_s) - RPY_TLOFSFIRST);
h = stacklet_new(st_thread, replay_thread_sub, NULL);
}
else {
@@ -787,6 +803,8 @@
assert(node->tid == target_thread_id);
h = node->h;
tdelete(node, &thread_tree_root, compare_replay_thread);
+ if (real_tloc != NULL)
+ *real_tloc = node->tloc;
free(node);
h = stacklet_switch(h);
@@ -1068,7 +1086,10 @@
target_thread_id = fetch_async_block();
_RPY_REVDB_PRINT("[THRD]", target_thread_id);
rpy_revdb.buf_limit = rpy_revdb.buf_p;
- st_outer_controller_h = stacklet_switch(st_outer_controller_h);
+ if (target_thread_id != current_thread_id) {
+ st_outer_controller_h = stacklet_switch(
+ st_outer_controller_h);
+ }
if (rpy_revdb.buf_limit == rpy_revdb.buf_p)
rpy_reverse_db_fetch(__FILE__, __LINE__);
return;
diff --git a/rpython/translator/revdb/test/test_thread.py b/rpython/translator/revdb/test/test_thread.py
--- a/rpython/translator/revdb/test/test_thread.py
+++ b/rpython/translator/revdb/test/test_thread.py
@@ -169,3 +169,41 @@
child.expect(ANSWER_READY, i, Ellipsis)
child.send(Message(CMD_FORWARD, 1))
child.expect(ANSWER_AT_END)
+
+
+class TestThreadLocal(InteractiveTests):
+ expected_stop_points = 1
+
+ def setup_class(cls):
+ from rpython.translator.revdb.test.test_basic import compile, run
+ class EC(object):
+ def __init__(self, value):
+ self.value = value
+ raw_thread_local = rthread.ThreadLocalReference(EC)
+
+ def bootstrap():
+ rthread.gc_thread_start()
+ _sleep(1)
+ ec = EC(4567)
+ raw_thread_local.set(ec)
+ revdb.stop_point()
+ print raw_thread_local.get().value
+ assert raw_thread_local.get() is ec
+ rthread.gc_thread_die()
+
+ def main(argv):
+ ec = EC(12)
+ raw_thread_local.set(ec)
+ rthread.start_new_thread(bootstrap, ())
+ _sleep(2)
+ print raw_thread_local.get().value
+ assert raw_thread_local.get() is ec
+ return 9
+
+ compile(cls, main, backendopt=False, thread=True)
+ assert run(cls, '') == '4567\n12\n'
+
+ def test_go_threadlocal(self):
+ child = self.replay()
+ child.send(Message(CMD_FORWARD, 1))
+ child.expect(ANSWER_AT_END)
More information about the pypy-commit
mailing list