Commit d94ccb7c158 by Armin Rigo

Test and fix

--HG--
branch : bag
parent 3665ef15024
......@@ -46,7 +46,7 @@ typedef union {
uintptr_t *deque_left, *deque_middle, *deque_right;
struct list_s *abort_list;
uint64_t start_time; /* the transaction's unique_start_time */
bool must_add_to_overflow_bags;
bool must_add_to_modified_bags;
};
char alignment[64]; /* 64-bytes alignment, to prevent false sharing */
} stm_bag_seg_t;
......@@ -74,7 +74,7 @@ stm_bag_t *stm_bag_create(void)
bs->deque_right = &block->items[0];
LIST_CREATE(bs->abort_list);
bs->start_time = 0;
bs->must_add_to_overflow_bags = false; /* currently young */
bs->must_add_to_modified_bags = false; /* currently young */
}
return bag;
}
......@@ -154,8 +154,7 @@ static stm_bag_seg_t *bag_check_start_time(stm_bag_t *bag)
bs->deque_middle = bs->deque_right;
list_clear(bs->abort_list);
bs->start_time = STM_PSEGMENT->unique_start_time;
bs->must_add_to_overflow_bags = false; /* not current transaction
any more */
bs->must_add_to_modified_bags = true;
/* We're about to modify the bag, so register an abort
callback now. */
......@@ -172,11 +171,11 @@ void stm_bag_add(stm_bag_t *bag, object_t *newobj)
stm_bag_seg_t *bs = bag_check_start_time(bag);
bag_add(bs, newobj);
if (bs->must_add_to_overflow_bags) {
bs->must_add_to_overflow_bags = false;
if (STM_PSEGMENT->overflow_bags == NULL)
LIST_CREATE(STM_PSEGMENT->overflow_bags);
LIST_APPEND(STM_PSEGMENT->overflow_bags, bag);
if (bs->must_add_to_modified_bags) {
bs->must_add_to_modified_bags = false;
if (STM_PSEGMENT->modified_bags == NULL)
LIST_CREATE(STM_PSEGMENT->modified_bags);
LIST_APPEND(STM_PSEGMENT->modified_bags, bag);
}
}
......@@ -214,9 +213,7 @@ void stm_bag_tracefn(stm_bag_t *bag, void trace(object_t **))
deque_trace(bs->deque_middle, bs->deque_right, trace);
/* this case should only be called if the bag is from the current
transaction (either in the nursery or already overflowed) */
bs->must_add_to_overflow_bags = true;
bs->must_add_to_modified_bags = true;
}
else {
int i;
......@@ -227,9 +224,9 @@ void stm_bag_tracefn(stm_bag_t *bag, void trace(object_t **))
}
}
static void collect_overflow_bags(void)
static void collect_modified_bags(void)
{
LIST_FOREACH_R(STM_PSEGMENT->overflow_bags, stm_bag_t *,
LIST_FOREACH_R(STM_PSEGMENT->modified_bags, stm_bag_t *,
stm_bag_tracefn(item, TRACE_FOR_MINOR_COLLECTION));
LIST_FREE(STM_PSEGMENT->overflow_bags);
LIST_FREE(STM_PSEGMENT->modified_bags);
}
static void collect_overflow_bags(void);
static void collect_modified_bags(void);
......@@ -206,9 +206,8 @@ struct stm_priv_segment_info_s {
/* regular finalizers (objs from the current transaction only) */
struct finalizers_s *finalizers;
/* list of bags that are overflow objects (current transaction but
outside the nursery) */
struct list_s *overflow_bags;
/* list of bags that are old but modified */
struct list_s *modified_bags;
};
enum /* safe_point */ {
......
......@@ -578,8 +578,8 @@ static void _do_minor_collection(bool commit)
if (STM_PSEGMENT->finalizers != NULL)
collect_objs_still_young_but_with_finalizers();
if (STM_PSEGMENT->overflow_bags != NULL)
collect_overflow_bags();
if (STM_PSEGMENT->modified_bags != NULL)
collect_modified_bags();
collect_oldrefs_to_nursery();
assert(list_is_empty(STM_PSEGMENT->old_objects_with_cards));
......
......@@ -130,7 +130,7 @@ void stm_setup(void)
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->overflow_bags = NULL;
pr->modified_bags = NULL;
pr->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * i;
highest_overflow_number = pr->overflow_number;
pr->pub.transaction_read_version = 0xff;
......@@ -175,7 +175,7 @@ void stm_teardown(void)
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->overflow_bags);
list_free(pr->modified_bags);
}
munmap(stm_object_pages, TOTAL_MEMORY);
......
......@@ -116,6 +116,19 @@ class TestBag(BaseTestBag):
assert lp1b != ffi.NULL
assert stm_get_char(lp1b) == 'N'
assert lp1b != lp1
#
self.commit_transaction()
self.start_transaction()
lp2 = stm_allocate(16)
stm_set_char(lp2, 'M')
b_add(b, lp2)
stm_minor_collect()
lp2b = b_pop(b)
assert lp2b != ffi.NULL
assert stm_get_char(lp2b) == 'M'
assert lp2b != lp2
#
stm_major_collect() # to get rid of the bag object
def test_transaction_local(self):
self.start_transaction()
......
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