Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit