Author: Remi Meier <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit