Author: Remi Meier <remi.me...@inf.ethz.ch> Branch: stmgc-c8-gcc Changeset: r79242:163412702b2b Date: 2015-08-27 10:25 +0200 http://bitbucket.org/pypy/pypy/changeset/163412702b2b/
Log: import stmgc with finalizer fixes 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 @@ -a3cb98b78053 +08c773f2b6ef diff --git a/rpython/translator/stm/src_stm/stm/core.c b/rpython/translator/stm/src_stm/stm/core.c --- a/rpython/translator/stm/src_stm/stm/core.c +++ b/rpython/translator/stm/src_stm/stm/core.c @@ -1365,9 +1365,10 @@ stm_rewind_jmp_forget(STM_SEGMENT->running_thread); } + commit_finalizers(); + /* XXX do we still need a s_mutex_lock() section here? */ s_mutex_lock(); - commit_finalizers(); /* update 'overflow_number' if needed */ if (STM_PSEGMENT->overflow_number_has_been_used) { diff --git a/rpython/translator/stm/src_stm/stm/finalizer.c b/rpython/translator/stm/src_stm/stm/finalizer.c --- a/rpython/translator/stm/src_stm/stm/finalizer.c +++ b/rpython/translator/stm/src_stm/stm/finalizer.c @@ -29,6 +29,9 @@ static void _commit_finalizers(void) { /* move finalizer lists to g_finalizers for major collections */ + while (__sync_lock_test_and_set(&g_finalizers.lock, 1) != 0) { + spin_loop(); + } if (STM_PSEGMENT->finalizers->run_finalizers != NULL) { /* copy 'STM_PSEGMENT->finalizers->run_finalizers' into @@ -60,6 +63,8 @@ free(STM_PSEGMENT->finalizers); STM_PSEGMENT->finalizers = NULL; + + __sync_lock_release(&g_finalizers.lock); } static void abort_finalizers(struct stm_priv_segment_info_s *pseg) @@ -389,7 +394,7 @@ static void deal_with_objects_with_finalizers(void) { /* for non-light finalizers */ - + assert(_has_mutex()); /* there is one 'objects_with_finalizers' list per segment. Objects that die at a major collection running in the same transaction as they were created will be put in the @@ -481,25 +486,44 @@ LIST_FREE(f->run_finalizers); } +/* XXX: can there be a race between _invoke_general_finalizers + and _commit_finalizer on g_finalizers (+other places?)? + XXX: what happens in _execute_finalizer if the transaction + conflicts (or fails to become inevitable) in a finalizer? + (the run_finalizers list is half-way cleared?) + XXX: according to translator.backendopt.finalizer, getfield_gc + for primitive types is a safe op in light finalizers. + I don't think that's correct in general (maybe if + getfield on *dying obj*). +*/ + static void _invoke_general_finalizers(stm_thread_local_t *tl) { /* called between transactions */ - static int lock = 0; - - if (__sync_lock_test_and_set(&lock, 1) != 0) { - /* can't acquire the lock: someone else is likely already - running this function, so don't wait. */ - return; - } - rewind_jmp_buf rjbuf; stm_rewind_jmp_enterframe(tl, &rjbuf); _stm_start_transaction(tl); + /* XXX: become inevitable, bc. otherwise, we would need to keep + around the original g_finalizers.run_finalizers to restore it + in case of an abort. */ + _stm_become_inevitable("finalizer-Tx"); - _execute_finalizers(&g_finalizers); + while (__sync_lock_test_and_set(&g_finalizers.lock, 1) != 0) { + /* somebody is adding more finalizers (_commit_finalizer()) */ + spin_loop(); + } + struct finalizers_s copy = g_finalizers; + assert(copy.running_next == NULL); + g_finalizers.run_finalizers = NULL; + /* others may add to g_finalizers again: */ + __sync_lock_release(&g_finalizers.lock); + + if (copy.run_finalizers != NULL) { + _execute_finalizers(©); + } _stm_commit_transaction(); stm_rewind_jmp_leaveframe(tl, &rjbuf); - __sync_lock_release(&lock); + LIST_FREE(copy.run_finalizers); } diff --git a/rpython/translator/stm/src_stm/stm/finalizer.h b/rpython/translator/stm/src_stm/stm/finalizer.h --- a/rpython/translator/stm/src_stm/stm/finalizer.h +++ b/rpython/translator/stm/src_stm/stm/finalizer.h @@ -1,5 +1,7 @@ /* Imported by rpython/translator/stm/import_stmgc.py */ +/* see deal_with_objects_with_finalizers() for explanation of these fields */ struct finalizers_s { + long lock; struct list_s *objects_with_finalizers; uintptr_t count_non_young; struct list_s *run_finalizers; _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit