Author: Armin Rigo <[email protected]>
Branch: hashtable
Changeset: r1487:89d9e799e056
Date: 2014-10-31 12:33 +0100
http://bitbucket.org/pypy/stmgc/changeset/89d9e799e056/
Log: More fixes: on abort, call the light finalizer before cleaning up
the nursery, and in the correct segment.
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -973,6 +973,8 @@
(int)pseg->transaction_state);
}
+ abort_finalizers(pseg);
+
/* throw away the content of the nursery */
long bytes_in_nursery = throw_away_nursery(pseg);
@@ -1061,8 +1063,6 @@
/* 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
@@ -58,30 +58,37 @@
STM_PSEGMENT->finalizers = NULL;
}
-static void abort_finalizers(void)
+static void abort_finalizers(struct stm_priv_segment_info_s *pseg)
{
/* like _commit_finalizers(), but forget everything from the
current transaction */
- if (STM_PSEGMENT->finalizers != NULL) {
- if (STM_PSEGMENT->finalizers->run_finalizers != NULL) {
- if (STM_PSEGMENT->finalizers->running_next != NULL) {
- *STM_PSEGMENT->finalizers->running_next = (uintptr_t)-1;
+ if (pseg->finalizers != NULL) {
+ if (pseg->finalizers->run_finalizers != NULL) {
+ if (pseg->finalizers->running_next != NULL) {
+ *pseg->finalizers->running_next = (uintptr_t)-1;
}
- list_free(STM_PSEGMENT->finalizers->run_finalizers);
+ list_free(pseg->finalizers->run_finalizers);
}
- list_free(STM_PSEGMENT->finalizers->objects_with_finalizers);
- free(STM_PSEGMENT->finalizers);
- STM_PSEGMENT->finalizers = NULL;
+ list_free(pseg->finalizers->objects_with_finalizers);
+ free(pseg->finalizers);
+ pseg->finalizers = NULL;
}
- /* also call the light finalizers for objects that are about to
+ /* call the light finalizers for objects that are about to
be forgotten from the current transaction */
- struct list_s *lst = STM_PSEGMENT->young_objects_with_light_finalizers;
+ char *old_gs_register = STM_SEGMENT->segment_base;
+ bool must_fix_gs = old_gs_register != pseg->pub.segment_base;
+
+ struct list_s *lst = pseg->young_objects_with_light_finalizers;
long i, count = list_count(lst);
if (lst > 0) {
for (i = 0; i < count; i++) {
object_t *obj = (object_t *)list_item(lst, i);
assert(_is_young(obj));
+ if (must_fix_gs) {
+ set_gs_register(pseg->pub.segment_base);
+ must_fix_gs = false;
+ }
stmcb_light_finalizer(obj);
}
list_clear(lst);
@@ -90,15 +97,22 @@
/* also deals with overflow objects: they are at the tail of
old_objects_with_light_finalizers (this list is kept in order
and we cannot add any already-committed object) */
- lst = STM_PSEGMENT->old_objects_with_light_finalizers;
+ lst = pseg->old_objects_with_light_finalizers;
count = list_count(lst);
while (count > 0) {
object_t *obj = (object_t *)list_item(lst, --count);
- if (!IS_OVERFLOW_OBJ(STM_PSEGMENT, obj))
+ if (!IS_OVERFLOW_OBJ(pseg, obj))
break;
lst->count = count;
+ if (must_fix_gs) {
+ set_gs_register(pseg->pub.segment_base);
+ must_fix_gs = false;
+ }
stmcb_light_finalizer(obj);
}
+
+ if (STM_SEGMENT->segment_base != old_gs_register)
+ set_gs_register(old_gs_register);
}
diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h
--- a/c7/stm/finalizer.h
+++ b/c7/stm/finalizer.h
@@ -14,7 +14,7 @@
static void teardown_finalizer(void);
static void _commit_finalizers(void);
-static void abort_finalizers(void);
+static void abort_finalizers(struct stm_priv_segment_info_s *);
#define commit_finalizers() do { \
if (STM_PSEGMENT->finalizers != NULL) \
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
@@ -9,6 +9,7 @@
#
@ffi.callback("void(object_t *)")
def light_finalizer(obj):
+ assert stm_get_obj_size(obj) == 48
segnum = lib.current_segment_num()
tlnum = '?'
for n, tl in enumerate(self.tls):
@@ -20,6 +21,10 @@
lib.stmcb_light_finalizer = light_finalizer
self._light_finalizer_keepalive = light_finalizer
+ def teardown_method(self, meth):
+ lib.stmcb_light_finalizer = ffi.NULL
+ BaseTest.teardown_method(self, meth)
+
def expect_finalized(self, objs, from_tlnum=None):
assert [obj for (obj, tlnum) in self.light_finalizers_called] == objs
if from_tlnum is not None:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit