[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