Author: Armin Rigo <ar...@tunes.org> Branch: stmgc-c4 Changeset: r65142:f0f5f39180fd Date: 2013-07-01 17:13 +0200 http://bitbucket.org/pypy/pypy/changeset/f0f5f39180fd/
Log: Fix start_new_thread with stm. diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py --- a/rpython/memory/gc/stmgc.py +++ b/rpython/memory/gc/stmgc.py @@ -53,9 +53,10 @@ needs_finalizer=False, is_finalizer_light=False, contains_weakptr=False): - ll_assert(not needs_finalizer, 'XXX') - ll_assert(not is_finalizer_light, 'XXX') - ll_assert(not contains_weakptr, 'XXX') + # XXX finalizers are ignored for now + #ll_assert(not needs_finalizer, 'XXX needs_finalizer') + #ll_assert(not is_finalizer_light, 'XXX is_finalizer_light') + ll_assert(not contains_weakptr, 'XXX contains_weakptr') # XXX call optimized versions, e.g. if size < GC_NURSERY_SECTION return llop.stm_allocate(llmemory.GCREF, size, typeid16) diff --git a/rpython/memory/gctransform/stmframework.py b/rpython/memory/gctransform/stmframework.py --- a/rpython/memory/gctransform/stmframework.py +++ b/rpython/memory/gctransform/stmframework.py @@ -50,12 +50,7 @@ class StmRootWalker(BaseRootWalker): def need_thread_support(self, gctransformer, getfn): - def thread_start(): - llop.stm_initialize(lltype.Void) - def thread_die(): - llop.stm_finalize(lltype.Void) - self.thread_start_ptr = getfn(thread_start, [], annmodel.s_None) - self.thread_die_ptr = getfn(thread_die, [], annmodel.s_None) + pass def walk_stack_roots(self, collect_stack_root): raise NotImplementedError diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -47,17 +47,21 @@ after_external_call._transaction_break_ = True def enter_callback_call(): - # XXX assumes that we're not called in a fresh new thread - llop.stm_begin_inevitable_transaction(lltype.Void) - return 0 + return llop.stm_enter_callback_call(lltype.Signed) enter_callback_call._dont_reach_me_in_del_ = True enter_callback_call._transaction_break_ = True -def leave_callback_call(ignored): - llop.stm_commit_transaction(lltype.Void) +def leave_callback_call(token): + llop.stm_leave_callback_call(lltype.Void, token) leave_callback_call._dont_reach_me_in_del_ = True leave_callback_call._transaction_break_ = True +def invoke_around_extcall(): + """Initialize the STM system. Must be called once from the start-up.""" + from rpython.rlib.objectmodel import invoke_around_extcall + invoke_around_extcall(before_external_call, after_external_call, + enter_callback_call, leave_callback_call) + # ____________________________________________________________ def make_perform_transaction(func, CONTAINERP): 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 @@ -441,6 +441,8 @@ 'stm_change_atomic': LLOp(), 'stm_get_atomic': LLOp(sideeffects=False), 'stm_perform_transaction':LLOp(), + 'stm_enter_callback_call':LLOp(), + 'stm_leave_callback_call':LLOp(), 'stm_threadlocalref_get': LLOp(sideeffects=False), 'stm_threadlocalref_set': 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 @@ -604,6 +604,8 @@ OP_STM_THREADLOCAL_GET = _OP_STM OP_STM_THREADLOCAL_SET = _OP_STM OP_STM_PERFORM_TRANSACTION = _OP_STM + OP_STM_ENTER_CALLBACK_CALL = _OP_STM + OP_STM_LEAVE_CALLBACK_CALL = _OP_STM def OP_PTR_NONZERO(self, op): diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py --- a/rpython/translator/stm/funcgen.py +++ b/rpython/translator/stm/funcgen.py @@ -151,6 +151,14 @@ arg1 = funcgen.expr(op.args[1]) return 'stm_perform_transaction((gcptr)%s, %s);' % (arg0, arg1) +def stm_enter_callback_call(funcgen, op): + result = funcgen.expr(op.result) + return '%s = stm_enter_callback_call();' % (result,) + +def stm_leave_callback_call(funcgen, op): + arg0 = funcgen.expr(op.args[0]) + return 'stm_leave_callback_call(%s);' % (arg0,) + def op_stm(funcgen, op): func = globals()[op.opname] diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -1539,15 +1539,14 @@ __thread gcptr stm_thread_local_obj; -int DescriptorInit(void) +void DescriptorInit(void) { if (GCFLAG_PREBUILT != PREBUILT_FLAGS) { stm_fatalerror("fix PREBUILT_FLAGS in stmgc.h by giving " "it the same value as GCFLAG_PREBUILT!\n"); } - - if (thread_descriptor == NULL) + else { revision_t i; struct tx_descriptor *d = stm_malloc(sizeof(struct tx_descriptor)); @@ -1595,16 +1594,14 @@ d->tx_next = stm_tx_head; if (d->tx_next != NULL) d->tx_next->tx_prev = d; stm_tx_head = d; + assert(thread_descriptor == NULL); thread_descriptor = d; dprintf(("[%lx] pthread %lx starting\n", (long)d->public_descriptor_index, (long)pthread_self())); stmgcpage_init_tls(); - return 1; } - else - return 0; } void DescriptorDone(void) diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h --- a/rpython/translator/stm/src_stm/et.h +++ b/rpython/translator/stm/src_stm/et.h @@ -194,7 +194,7 @@ _Bool stm_has_got_any_lock(struct tx_descriptor *); struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *); -int DescriptorInit(void); +void DescriptorInit(void); void DescriptorDone(void); #endif /* _ET_H */ diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision --- a/rpython/translator/stm/src_stm/revision +++ b/rpython/translator/stm/src_stm/revision @@ -1,1 +1,1 @@ -bf56c12295c8 +637f6c9d19f7 diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h --- a/rpython/translator/stm/src_stm/stmgc.h +++ b/rpython/translator/stm/src_stm/stmgc.h @@ -49,6 +49,12 @@ void stm_initialize(void); void stm_finalize(void); +/* alternate initializers/deinitializers, to use for places that may or + may not be recursive, like callbacks from C code. The return value + of the first one must be passed as argument to the second. */ +int stm_enter_callback_call(void); +void stm_leave_callback_call(int); + /* read/write barriers (the most general versions only for now) */ #if 0 // (optimized version below) gcptr stm_read_barrier(gcptr); diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c --- a/rpython/translator/stm/src_stm/stmsync.c +++ b/rpython/translator/stm/src_stm/stmsync.c @@ -78,29 +78,46 @@ d->max_aborts = max_aborts; } +int stm_enter_callback_call(void) +{ + int token = (thread_descriptor == NULL); + if (token == 1) { + stmgcpage_acquire_global_lock(); + DescriptorInit(); + stmgc_init_nursery(); + init_shadowstack(); + stmgcpage_release_global_lock(); + } + BeginInevitableTransaction(); + return token; +} + +void stm_leave_callback_call(int token) +{ + if (token == 1) + stmgc_minor_collect(); /* force everything out of the nursery */ + + CommitTransaction(); + + if (token == 1) { + stmgcpage_acquire_global_lock(); + done_shadowstack(); + stmgc_done_nursery(); + DescriptorDone(); + stmgcpage_release_global_lock(); + } +} + void stm_initialize(void) { - stmgcpage_acquire_global_lock(); - int r = DescriptorInit(); + int r = stm_enter_callback_call(); if (r != 1) - stm_fatalerror("stm_initialize: DescriptorInit failure\n"); - stmgc_init_nursery(); - init_shadowstack(); - //stmgcpage_init_tls(); - stmgcpage_release_global_lock(); - BeginInevitableTransaction(); + stm_fatalerror("stm_initialize: already initialized\n"); } void stm_finalize(void) { - stmgc_minor_collect(); /* force everything out of the nursery */ - CommitTransaction(); - stmgcpage_acquire_global_lock(); - //stmgcpage_done_tls(); - done_shadowstack(); - stmgc_done_nursery(); - DescriptorDone(); - stmgcpage_release_global_lock(); + stm_leave_callback_call(1); } /************************************************************/ diff --git a/rpython/translator/stm/test/targetdemo2.py b/rpython/translator/stm/test/targetdemo2.py --- a/rpython/translator/stm/test/targetdemo2.py +++ b/rpython/translator/stm/test/targetdemo2.py @@ -1,7 +1,7 @@ import time from rpython.rlib import rthread from rpython.rlib import rstm, jit -from rpython.rlib.objectmodel import invoke_around_extcall, we_are_translated +from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.objectmodel import compute_identity_hash from rpython.rlib.debug import ll_assert from rpython.rtyper.lltypesystem import lltype, rffi, rclass @@ -250,8 +250,7 @@ def setup_threads(): #space.threadlocals.setup_threads(space) bootstrapper.setup() - invoke_around_extcall(rstm.before_external_call, rstm.after_external_call, - rstm.enter_callback_call, rstm.leave_callback_call) + rstm.invoke_around_extcall() def start_thread(args): bootstrapper.acquire(args) diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -62,12 +62,11 @@ glob = Global() # def threadfn(): - rthread.gc_thread_start() x = Global() x.value = 0 glob.seen = x - rthread.gc_thread_die() def entry_point(argv): + rstm.invoke_around_extcall() glob.seen = None rthread.start_new_thread(threadfn, ()) while glob.seen is None: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit