Author: Armin Rigo <[email protected]>
Branch: finalizer
Changeset: r1460:97dc15596c92
Date: 2014-10-06 15:59 +0200
http://bitbucket.org/pypy/stmgc/changeset/97dc15596c92/

Log:    Start on light finalizers

diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -198,6 +198,9 @@
 
     /* marker where this thread became inevitable */
     stm_loc_marker_t marker_inev;
+
+    /* Lightweight finalizers */
+    struct list_s *young_objects_with_light_finalizers;
 };
 
 enum /* safe_point */ {
diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c
new file mode 100644
--- /dev/null
+++ b/c7/stm/finalizer.c
@@ -0,0 +1,20 @@
+
+
+void (*stmcb_light_finalizer)(object_t *);
+
+void stm_enable_light_finalizer(object_t *obj)
+{
+    STM_PSEGMENT->young_objects_with_light_finalizers = list_append(
+        STM_PSEGMENT->young_objects_with_light_finalizers, (uintptr_t)obj);
+}
+
+static void deal_with_young_objects_with_finalizers(void)
+{
+    struct list_s *lst = STM_PSEGMENT->young_objects_with_light_finalizers;
+    long i, count = list_count(lst);
+    for (i = 0; i < count; i++) {
+        object_t* obj = (object_t *)list_item(lst, i);
+        stmcb_light_finalizer(obj);
+    }
+    list_clear(lst);
+}
diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h
new file mode 100644
--- /dev/null
+++ b/c7/stm/finalizer.h
@@ -0,0 +1,2 @@
+
+static void deal_with_young_objects_with_finalizers(void);
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -559,6 +559,7 @@
 
     /* now all surviving nursery objects have been moved out */
     stm_move_young_weakrefs();
+    deal_with_young_objects_with_finalizers();
 
     throw_away_nursery(get_priv_segment(STM_SEGMENT->segment_num));
 
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -128,6 +128,7 @@
         pr->nursery_objects_shadows = tree_create();
         pr->callbacks_on_commit_and_abort[0] = tree_create();
         pr->callbacks_on_commit_and_abort[1] = tree_create();
+        pr->young_objects_with_light_finalizers = list_create();
         pr->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * i;
         highest_overflow_number = pr->overflow_number;
         pr->pub.transaction_read_version = 0xff;
@@ -169,6 +170,7 @@
         tree_free(pr->nursery_objects_shadows);
         tree_free(pr->callbacks_on_commit_and_abort[0]);
         tree_free(pr->callbacks_on_commit_and_abort[1]);
+        list_free(pr->young_objects_with_light_finalizers);
     }
 
     munmap(stm_object_pages, TOTAL_MEMORY);
diff --git a/c7/stmgc.c b/c7/stmgc.c
--- a/c7/stmgc.c
+++ b/c7/stmgc.c
@@ -16,6 +16,7 @@
 #include "stm/weakref.h"
 #include "stm/marker.h"
 #include "stm/prof.h"
+#include "stm/finalizer.h"
 
 #include "stm/misc.c"
 #include "stm/list.c"
@@ -37,3 +38,4 @@
 #include "stm/marker.c"
 #include "stm/prof.c"
 #include "stm/rewind_setjmp.c"
+#include "stm/finalizer.c"
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -505,6 +505,13 @@
 } while (0)
 
 
+/* Support for light finalizers.  This is a simple version of
+   finalizers that guarantees not to do anything fancy, like not
+   resurrecting objects. */
+void (*stmcb_light_finalizer)(object_t *);
+void stm_enable_light_finalizer(object_t *);
+
+
 /* ==================== END ==================== */
 
 #endif
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -158,6 +158,9 @@
 void stm_push_marker(stm_thread_local_t *, uintptr_t, object_t *);
 void stm_update_marker_num(stm_thread_local_t *, uintptr_t);
 void stm_pop_marker(stm_thread_local_t *);
+
+void (*stmcb_light_finalizer)(object_t *);
+void stm_enable_light_finalizer(object_t *);
 """)
 
 
diff --git a/c7/test/test_finalizer.py b/c7/test/test_finalizer.py
new file mode 100644
--- /dev/null
+++ b/c7/test/test_finalizer.py
@@ -0,0 +1,33 @@
+from support import *
+import py
+
+
+class TestFinalizer(BaseTest):
+
+    def setup_method(self, meth):
+        BaseTest.setup_method(self, meth)
+        #
+        @ffi.callback("void(object_t *)")
+        def light_finalizer(obj):
+            self.light_finalizers_called.append(obj)
+        self.light_finalizers_called = []
+        lib.stmcb_light_finalizer = light_finalizer
+        self._light_finalizer_keepalive = light_finalizer
+
+    def expect_finalized(self, objs):
+        assert self.light_finalizers_called == objs
+        self.light_finalizers_called = []
+
+    def test_no_finalizer(self):
+        self.start_transaction()
+        lp1 = stm_allocate(48)
+        self.commit_transaction()
+        self.expect_finalized([])
+
+    def test_young_light_finalizer(self):
+        self.start_transaction()
+        lp1 = stm_allocate(48)
+        lib.stm_enable_light_finalizer(lp1)
+        self.expect_finalized([])
+        self.commit_transaction()
+        self.expect_finalized([lp1])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to