Author: Armin Rigo <[email protected]>
Branch: bag
Changeset: r1584:3665ef15024d
Date: 2015-01-24 15:22 +0100
http://bitbucket.org/pypy/stmgc/changeset/3665ef15024d/
Log: Test and fix
diff --git a/c7/stm/bag.c b/c7/stm/bag.c
--- a/c7/stm/bag.c
+++ b/c7/stm/bag.c
@@ -46,6 +46,7 @@
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;
};
char alignment[64]; /* 64-bytes alignment, to prevent false sharing */
} stm_bag_seg_t;
@@ -73,6 +74,7 @@
bs->deque_right = &block->items[0];
LIST_CREATE(bs->abort_list);
bs->start_time = 0;
+ bs->must_add_to_overflow_bags = false; /* currently young */
}
return bag;
}
@@ -80,6 +82,18 @@
void stm_bag_free(stm_bag_t *bag)
{
int i;
+
+ s_mutex_lock();
+ for (i = 0; i < STM_NB_SEGMENTS; i++) {
+ stm_bag_seg_t *bs = &bag->by_segment[i];
+ struct stm_segment_info_s *pub = get_segment(i + 1);
+ stm_thread_local_t *tl = pub->running_thread;
+ if (tl != NULL && tl->associated_segment_num == i + 1) {
+ stm_call_on_abort(tl, bs, NULL);
+ }
+ }
+ s_mutex_unlock();
+
for (i = 0; i < STM_NB_SEGMENTS; i++) {
stm_bag_seg_t *bs = &bag->by_segment[i];
struct deque_block_s *block = deque_block(bs->deque_left);
@@ -91,17 +105,6 @@
LIST_FREE(bs->abort_list);
}
- s_mutex_lock();
- for (i = 0; i < STM_NB_SEGMENTS; i++) {
- stm_bag_seg_t *bs = &bag->by_segment[i];
- struct stm_segment_info_s *pub = get_segment(i + 1);
- stm_thread_local_t *tl = pub->running_thread;
- if (tl->associated_segment_num == i + 1) {
- stm_call_on_abort(tl, bs, NULL);
- }
- }
- s_mutex_unlock();
-
free(bag);
}
@@ -151,6 +154,8 @@
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 */
/* We're about to modify the bag, so register an abort
callback now. */
@@ -166,6 +171,13 @@
{
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);
+ }
}
object_t *stm_bag_try_pop(stm_bag_t *bag)
@@ -201,6 +213,10 @@
stm_bag_seg_t *bs = &bag->by_segment[i];
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;
}
else {
int i;
@@ -210,3 +226,10 @@
}
}
}
+
+static void collect_overflow_bags(void)
+{
+ LIST_FOREACH_R(STM_PSEGMENT->overflow_bags, stm_bag_t *,
+ stm_bag_tracefn(item, TRACE_FOR_MINOR_COLLECTION));
+ LIST_FREE(STM_PSEGMENT->overflow_bags);
+}
diff --git a/c7/stm/bag.h b/c7/stm/bag.h
new file mode 100644
--- /dev/null
+++ b/c7/stm/bag.h
@@ -0,0 +1,2 @@
+
+static void collect_overflow_bags(void);
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -205,6 +205,10 @@
/* 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;
};
enum /* safe_point */ {
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -578,6 +578,9 @@
if (STM_PSEGMENT->finalizers != NULL)
collect_objs_still_young_but_with_finalizers();
+ if (STM_PSEGMENT->overflow_bags != NULL)
+ collect_overflow_bags();
+
collect_oldrefs_to_nursery();
assert(list_is_empty(STM_PSEGMENT->old_objects_with_cards));
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -130,6 +130,7 @@
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->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * i;
highest_overflow_number = pr->overflow_number;
pr->pub.transaction_read_version = 0xff;
@@ -174,6 +175,7 @@
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);
}
munmap(stm_object_pages, TOTAL_MEMORY);
diff --git a/c7/stmgc.c b/c7/stmgc.c
--- a/c7/stmgc.c
+++ b/c7/stmgc.c
@@ -16,6 +16,7 @@
#include "stm/weakref.h"
#include "stm/marker.h"
#include "stm/finalizer.h"
+#include "stm/bag.h"
#include "stm/misc.c"
#include "stm/list.c"
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
@@ -93,6 +93,15 @@
assert lp1b != ffi.NULL
assert stm_get_char(lp1b) == 'N'
assert lp1b != lp1
+ #
+ 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
def test_keepalive_major(self):
self.start_transaction()
diff --git a/c7/test/test_hashtable.py b/c7/test/test_hashtable.py
--- a/c7/test/test_hashtable.py
+++ b/c7/test/test_hashtable.py
@@ -146,6 +146,16 @@
assert lp1b != ffi.NULL
assert stm_get_char(lp1b) == 'N'
assert lp1b != lp1
+ #
+ lp2 = stm_allocate(16)
+ stm_set_char(lp2, 'M')
+ tl0 = self.tls[self.current_thread]
+ htset(h, 1235, lp2, tl0)
+ stm_minor_collect()
+ lp2b = htget(h, 1235)
+ assert lp2b != ffi.NULL
+ assert stm_get_char(lp2b) == 'M'
+ assert lp2b != lp2
def test_keepalive_major(self):
lp1 = stm_allocate_old(16)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit