[pypy-commit] stmgc finalizer: Tweak invocation of same-transaction finalizers

arigo noreply at buildbot.pypy.org
Fri Oct 17 11:59:48 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: finalizer
Changeset: r1475:512c75ab693f
Date: 2014-10-17 11:59 +0200
http://bitbucket.org/pypy/stmgc/changeset/512c75ab693f/

Log:	Tweak invocation of same-transaction finalizers

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -808,6 +808,9 @@
 
 void stm_commit_transaction(void)
 {
+ restart_all:
+    exec_local_finalizers();
+
     assert(!_has_mutex());
     assert(STM_PSEGMENT->safe_point == SP_RUNNING);
     assert(STM_PSEGMENT->running_pthread == pthread_self());
@@ -825,6 +828,11 @@
        Important: we should not call cond_wait() in the meantime. */
     synchronize_all_threads(STOP_OTHERS_UNTIL_MUTEX_UNLOCK);
 
+    if (any_local_finalizers()) {
+        s_mutex_unlock();
+        goto restart_all;
+    }
+
     /* detect conflicts */
     if (detect_write_read_conflicts())
         goto restart;
diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c
--- a/c7/stm/finalizer.c
+++ b/c7/stm/finalizer.c
@@ -345,9 +345,9 @@
     LIST_FREE(_finalizer_emptystack);
 }
 
-static void execute_finalizers(struct finalizers_s *f)
+static void _execute_finalizers(struct finalizers_s *f)
 {
-    if (f == NULL || f->run_finalizers == NULL)
+    if (f->run_finalizers == NULL)
         return;   /* nothing to do */
 
  restart:
@@ -395,7 +395,7 @@
     stm_rewind_jmp_enterframe(tl, &rjbuf);
     stm_start_transaction(tl);
 
-    execute_finalizers(&g_finalizers);
+    _execute_finalizers(&g_finalizers);
 
     stm_commit_transaction();
     stm_rewind_jmp_leaveframe(tl, &rjbuf);
diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h
--- a/c7/stm/finalizer.h
+++ b/c7/stm/finalizer.h
@@ -37,4 +37,11 @@
         _invoke_general_finalizers(tl);         \
 } while (0)
 
-static void execute_finalizers(struct finalizers_s *f);
+static void _execute_finalizers(struct finalizers_s *f);
+
+#define any_local_finalizers() (STM_PSEGMENT->finalizers != NULL &&         \
+                               STM_PSEGMENT->finalizers->run_finalizers != NULL)
+#define exec_local_finalizers()  do {                   \
+    if (any_local_finalizers())                         \
+        _execute_finalizers(STM_PSEGMENT->finalizers);  \
+} while (0)
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -153,8 +153,7 @@
     }
 
     s_mutex_unlock();
-
-    execute_finalizers(STM_PSEGMENT->finalizers);
+    exec_local_finalizers();
 }
 
 
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -228,6 +228,7 @@
     assert(_stm_in_transaction(tl));
     set_gs_register(get_segment_base(tl->associated_segment_num));
     assert(STM_SEGMENT->running_thread == tl);
+    exec_local_finalizers();
 }
 
 #if STM_TESTS
diff --git a/c7/test/test_finalizer.py b/c7/test/test_finalizer.py
--- a/c7/test/test_finalizer.py
+++ b/c7/test/test_finalizer.py
@@ -167,3 +167,18 @@
         self.expect_finalized([])
         self.commit_transaction()
         self.expect_finalized([lp1])
+
+    def test_run_cb_for_all_threads(self):
+        self.start_transaction()
+        lp1 = stm_allocate_with_finalizer(48)
+        print lp1
+        #
+        self.switch(1)
+        self.start_transaction()
+        lp2 = stm_allocate_with_finalizer(56)
+        print lp2
+
+        self.expect_finalized([])
+        stm_major_collect()
+        self.switch(0)
+        self.expect_finalized([lp2, lp1])


More information about the pypy-commit mailing list