Commit 89d9e799e05 by Armin Rigo

More fixes: on abort, call the light finalizer before cleaning up the

nursery, and in the correct segment.

--HG--
branch : hashtable
parent 9b55442913f
......@@ -973,6 +973,8 @@ static void abort_data_structures_from_segment_num(int segment_num)
(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 @@ static stm_thread_local_t *abort_with_mutex_no_longjmp(void)
/* 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
......
......@@ -58,30 +58,37 @@ static void _commit_finalizers(void)
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 @@ static void abort_finalizers(void)
/* 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);
}
......
......@@ -14,7 +14,7 @@ static void setup_finalizer(void);
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) \
......
......@@ -9,6 +9,7 @@ class TestLightFinalizer(BaseTest):
#
@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 @@ class TestLightFinalizer(BaseTest):
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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment