[pypy-commit] stmgc bag: in-progress
arigo
noreply at buildbot.pypy.org
Sat Jan 24 10:56:51 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: bag
Changeset: r1581:22510e2df160
Date: 2015-01-24 10:57 +0100
http://bitbucket.org/pypy/stmgc/changeset/22510e2df160/
Log: in-progress
diff --git a/c7/stm/bag.c b/c7/stm/bag.c
--- a/c7/stm/bag.c
+++ b/c7/stm/bag.c
@@ -104,16 +104,34 @@
return NULL;
}
struct deque_block_s *block = deque_block(bs->deque_left);
+ bool any_old_item_to_pop = (bs->deque_left != bs->deque_middle);
uintptr_t result = *bs->deque_left++;
if (bs->deque_left == &block->items[DEQUE_BLOCK_SIZE]) {
bs->deque_left = &block->next->items[0];
deque_free_block(block);
}
+ if (!any_old_item_to_pop) {
+ bs->deque_middle = bs->deque_left;
+ }
return (object_t *)result;
}
-void stm_bag_tracefn(stm_bag_t *bag, void visit(object_t **))
+void stm_bag_tracefn(stm_bag_t *bag, void trace(object_t **))
{
- abort();
+ if (trace == TRACE_FOR_MINOR_COLLECTION) {
+ /* only trace the items added in the current transaction;
+ the rest is already old and cannot point into the nursery. */
+ int i = STM_SEGMENT->segment_num - 1;
+ struct stm_bag_seg_s *bs = &bag->by_segment[i];
+
+ deque_trace(bs->deque_middle, bs->deque_right, trace);
+ }
+ else {
+ int i;
+ for (i = 0; i < NB_SEGMENTS; i++) {
+ struct stm_bag_seg_s *bs = &bag->by_segment[i];
+ deque_trace(bs->deque_left, bs->deque_right, trace);
+ }
+ }
}
diff --git a/c7/stm/list.c b/c7/stm/list.c
--- a/c7/stm/list.c
+++ b/c7/stm/list.c
@@ -212,3 +212,29 @@
db->next = NULL;
return db;
}
+
+static void deque_trace(uintptr_t *start, uintptr_t *stop,
+ void trace(object_t **))
+{
+ struct deque_block_s *block = deque_block(start);
+ struct deque_block_s *last_block = deque_block(stop);
+ uintptr_t *end;
+
+ while (1) {
+ if (block == last_block)
+ end = stop;
+ else
+ end = &block->items[DEQUE_BLOCK_SIZE];
+
+ while (start != end) {
+ trace((object_t **)start);
+ start++;
+ }
+
+ if (block == last_block)
+ break;
+
+ block = block->next;
+ start = &block->items[0];
+ }
+}
diff --git a/c7/stm/list.h b/c7/stm/list.h
--- a/c7/stm/list.h
+++ b/c7/stm/list.h
@@ -246,3 +246,5 @@
struct deque_block_s *block = deque_block(inner_ptr);
return (inner_ptr == &block->items[index]);
}
+
+static void deque_trace(uintptr_t *start, uintptr_t *stop, void (object_t **));
diff --git a/c7/test/test_bag.py b/c7/test/test_bag.py
--- a/c7/test/test_bag.py
+++ b/c7/test/test_bag.py
@@ -79,3 +79,55 @@
assert got == lp
py.test.raises(BagLooksEmpty, b_pop, q)
py.test.raises(BagLooksEmpty, b_pop, q)
+
+ def test_keepalive_minor(self):
+ self.start_transaction()
+ b = self.allocate_bag()
+ self.push_root(b)
+ lp1 = stm_allocate(16)
+ stm_set_char(lp1, 'N')
+ b_add(b, lp1)
+ stm_minor_collect()
+ b = self.pop_root()
+ lp1b = b_pop(b)
+ assert lp1b != ffi.NULL
+ assert stm_get_char(lp1b) == 'N'
+ assert lp1b != lp1
+
+ def test_keepalive_major(self):
+ self.start_transaction()
+ b = self.allocate_bag()
+ self.push_root(b)
+ lp1 = stm_allocate(16)
+ stm_set_char(lp1, 'N')
+ b_add(b, lp1)
+ stm_major_collect()
+ b = self.pop_root()
+ lp1b = b_pop(b)
+ assert lp1b != ffi.NULL
+ assert stm_get_char(lp1b) == 'N'
+ assert lp1b != lp1
+
+ def test_transaction_local(self):
+ self.start_transaction()
+ q = self.allocate_bag()
+ self.push_root(q)
+ self.commit_transaction()
+ q = self.pop_root()
+ #
+ self.start_transaction()
+ lp1 = stm_allocate(16)
+ b_add(q, lp1)
+ #
+ self.switch(1)
+ self.start_transaction()
+ lp2 = stm_allocate(16)
+ b_add(q, lp2)
+ got = b_pop(q)
+ assert got == lp2
+ #
+ self.switch(0)
+ got = b_pop(q)
+ assert got == lp1
+ #
+ stm_major_collect() # to get rid of the bag object
More information about the pypy-commit
mailing list