[pypy-commit] stmgc finalizer: in-progress

arigo noreply at buildbot.pypy.org
Thu Oct 16 06:09:19 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: finalizer
Changeset: r1470:ca1d0b20ebce
Date: 2014-10-16 06:09 +0200
http://bitbucket.org/pypy/stmgc/changeset/ca1d0b20ebce/

Log:	in-progress

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -374,6 +374,7 @@
     assert(tree_is_cleared(STM_PSEGMENT->callbacks_on_commit_and_abort[1]));
     assert(STM_PSEGMENT->objects_pointing_to_nursery == NULL);
     assert(STM_PSEGMENT->large_overflow_objects == NULL);
+    assert(STM_PSEGMENT->finalizers == NULL);
 #ifndef NDEBUG
     /* this should not be used when objects_pointing_to_nursery == NULL */
     STM_PSEGMENT->modified_old_objects_markers_num_old = 99999999999999999L;
@@ -867,10 +868,13 @@
     }
 
     /* done */
+    stm_thread_local_t *tl = STM_SEGMENT->running_thread;
     _finish_transaction(STM_TRANSACTION_COMMIT);
     /* cannot access STM_SEGMENT or STM_PSEGMENT from here ! */
 
     s_mutex_unlock();
+
+    invoke_general_finalizers(tl);
 }
 
 void stm_abort_transaction(void)
@@ -1048,6 +1052,8 @@
     /* invoke the callbacks */
     invoke_and_clear_user_callbacks(1);   /* for abort */
 
+    abort_finalizers();
+
     if (is_abort(STM_SEGMENT->nursery_end)) {
         /* done aborting */
         STM_SEGMENT->nursery_end = pause_signalled ? NSE_SIGPAUSE
diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c
--- a/c7/stm/finalizer.c
+++ b/c7/stm/finalizer.c
@@ -9,7 +9,7 @@
 {
     f->objects_with_finalizers = list_create();
     f->run_finalizers = NULL;
-    f->running_current = NULL;
+    f->running_next = NULL;
 }
 
 static void setup_finalizer(void)
@@ -57,6 +57,21 @@
     STM_PSEGMENT->finalizers = NULL;
 }
 
+static void _abort_finalizers(void)
+{
+    /* like _commit_finalizers(), but forget everything from the
+       current transaction */
+    if (STM_PSEGMENT->finalizers->run_finalizers != NULL) {
+        if (STM_PSEGMENT->finalizers->running_next != NULL) {
+            *STM_PSEGMENT->finalizers->running_next = (uintptr_t)-1;
+        }
+        list_free(STM_PSEGMENT->finalizers->run_finalizers);
+    }
+    list_free(STM_PSEGMENT->finalizers->objects_with_finalizers);
+    free(STM_PSEGMENT->finalizers);
+    STM_PSEGMENT->finalizers = NULL;
+}
+
 
 void stm_enable_light_finalizer(object_t *obj)
 {
@@ -68,11 +83,13 @@
 
 object_t *stm_allocate_with_finalizer(ssize_t size_rounded_up)
 {
-    if (STM_PSEGMENT->finalizers == NULL)
-    struct finalizers_s *f = malloc(sizeof(struct finalizers_s));
-    if (f == NULL)
-        stm_fatalerror("out of memory in create_finalizers");   /* XXX */
-        STM_PSEGMENT->finalizers = create_finalizers();
+    if (STM_PSEGMENT->finalizers == NULL) {
+        struct finalizers_s *f = malloc(sizeof(struct finalizers_s));
+        if (f == NULL)
+            stm_fatalerror("out of memory in create_finalizers");   /* XXX */
+        init_finalizers(f);
+        STM_PSEGMENT->finalizers = f;
+    }
 
     object_t *obj = _allocate_old(size_rounded_up);
     LIST_APPEND(STM_PSEGMENT->finalizers->objects_with_finalizers, obj);
@@ -275,6 +292,7 @@
             _recursively_bump_finalization_state(x, 3);
         }
         else {
+            struct list_s *lst = f->objects_with_finalizers;
             list_set_item(lst, lst->count++, (uintptr_t)x);
         }
     }
@@ -357,7 +375,7 @@
     LIST_FREE(f->run_finalizers);
 }
 
-static void _invoke_general_finalizers(void)
+static void _invoke_general_finalizers(stm_thread_local_t *tl)
 {
     /* called between transactions */
     static int lock = 0;
diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h
--- a/c7/stm/finalizer.h
+++ b/c7/stm/finalizer.h
@@ -13,19 +13,27 @@
 static void teardown_finalizer(void);
 
 static void _commit_finalizers(void);
+static void _abort_finalizers(void);
 
 #define commit_finalizers()   do {              \
     if (STM_PSEGMENT->finalizers != NULL)       \
         _commit_finalizers();                   \
 } while (0)
 
+#define abort_finalizers()   do {               \
+    if (STM_PSEGMENT->finalizers != NULL)       \
+        _abort_finalizers();                    \
+} while (0)
+
 
 /* regular finalizers (objs from already-committed transactions) */
 static struct finalizers_s g_finalizers;
 
-static void _invoke_general_finalizers(void);
+static void _invoke_general_finalizers(stm_thread_local_t *tl);
 
-#define invoke_general_finalizers()    do {     \
-    if (g_finalizers->run_finalizers != NULL)   \
-        _invoke_general_finalizers();           \
+#define invoke_general_finalizers(tl)    do {   \
+    if (g_finalizers.run_finalizers != NULL)    \
+        _invoke_general_finalizers(tl);         \
 } while (0)
+
+static void execute_finalizers(struct finalizers_s *f);
diff --git a/c7/stm/list.c b/c7/stm/list.c
--- a/c7/stm/list.c
+++ b/c7/stm/list.c
@@ -34,7 +34,7 @@
                                   uintptr_t slicestart)
 {
     if (lst2->count <= slicestart)
-        return;
+        return lst;
     uintptr_t baseindex = lst->count;
     lst->count = baseindex + lst2->count - slicestart;
     uintptr_t lastindex = lst->count - 1;
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -130,8 +130,6 @@
         pr->callbacks_on_commit_and_abort[1] = tree_create();
         pr->young_objects_with_light_finalizers = list_create();
         pr->old_objects_with_light_finalizers = list_create();
-        pr->objects_with_finalizers = list_create();
-        pr->run_finalizers = list_create();
         pr->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * i;
         highest_overflow_number = pr->overflow_number;
         pr->pub.transaction_read_version = 0xff;
@@ -176,8 +174,6 @@
         tree_free(pr->callbacks_on_commit_and_abort[1]);
         list_free(pr->young_objects_with_light_finalizers);
         list_free(pr->old_objects_with_light_finalizers);
-        list_free(pr->objects_with_finalizers);
-        list_free(pr->run_finalizers);
     }
 
     munmap(stm_object_pages, TOTAL_MEMORY);


More information about the pypy-commit mailing list