Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit