Author: Armin Rigo <[email protected]>
Branch:
Changeset: r952:37981d65bc52
Date: 2014-03-04 19:43 +0100
http://bitbucket.org/pypy/stmgc/changeset/37981d65bc52/
Log: A final clean-up round of bug fixes. Now demo_random seems to pass
again.
diff --git a/c7/stm/contention.c b/c7/stm/contention.c
--- a/c7/stm/contention.c
+++ b/c7/stm/contention.c
@@ -215,8 +215,8 @@
We don't have to wake it up right now, but we know it will
abort as soon as it wakes up. We can safely force it to
reset its state now. */
- dprintf(("reset other modified\n"));
- reset_modified_from_other_segments(other_segment_num);
+ dprintf(("killing data structures\n"));
+ abort_data_structures_from_segment_num(other_segment_num);
}
dprintf(("killed other thread\n"));
}
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -448,6 +448,29 @@
list_clear(pseg->modified_old_objects);
}
+static void abort_data_structures_from_segment_num(int segment_num)
+{
+ /* This function clears the content of the given segment undergoing
+ an abort. It is called from abort_with_mutex(), but also sometimes
+ from other threads that figure out that this segment should abort.
+ In the latter case, make sure that this segment is currently at
+ a safe point (not SP_RUNNING).
+ */
+ struct stm_priv_segment_info_s *pseg = get_priv_segment(segment_num);
+
+ /* throw away the content of the nursery */
+ throw_away_nursery(pseg);
+
+ /* reset all the modified objects (incl. re-adding GCFLAG_WRITE_BARRIER) */
+ reset_modified_from_other_segments(segment_num);
+
+ /* reset the tl->shadowstack and thread_local_obj to their original
+ value before the transaction start */
+ stm_thread_local_t *tl = pseg->pub.running_thread;
+ tl->shadowstack = pseg->shadowstack_at_start_of_transaction;
+ tl->thread_local_obj = pseg->threadlocal_at_start_of_transaction;
+}
+
static void abort_with_mutex(void)
{
dprintf(("~~~ ABORT\n"));
@@ -463,16 +486,9 @@
}
assert(STM_PSEGMENT->running_pthread == pthread_self());
- /* throw away the content of the nursery */
- throw_away_nursery();
-
- /* reset all the modified objects (incl. re-adding GCFLAG_WRITE_BARRIER) */
- reset_modified_from_other_segments(STM_SEGMENT->segment_num);
+ abort_data_structures_from_segment_num(STM_SEGMENT->segment_num);
stm_jmpbuf_t *jmpbuf_ptr = STM_SEGMENT->jmpbuf_ptr;
- stm_thread_local_t *tl = STM_SEGMENT->running_thread;
- tl->shadowstack = STM_PSEGMENT->shadowstack_at_start_of_transaction;
- tl->thread_local_obj = STM_PSEGMENT->threadlocal_at_start_of_transaction;
if (STM_SEGMENT->nursery_end == NSE_SIGABORT)
STM_SEGMENT->nursery_end = NURSERY_END; /* done aborting */
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -183,6 +183,7 @@
static void teardown_core(void);
static void abort_with_mutex(void) __attribute__((noreturn));
+static void abort_data_structures_from_segment_num(int segment_num);
static inline bool was_read_remote(char *base, object_t *obj,
uint8_t other_transaction_read_version)
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -196,29 +196,29 @@
_collect_now(item));
}
-static void throw_away_nursery(void)
+static void throw_away_nursery(struct stm_priv_segment_info_s *pseg)
{
/* reset the nursery by zeroing it */
size_t size;
char *realnursery;
- realnursery = REAL_ADDRESS(STM_SEGMENT->segment_base, _stm_nursery_start);
- size = STM_SEGMENT->nursery_current - (stm_char *)_stm_nursery_start;
+ realnursery = REAL_ADDRESS(pseg->pub.segment_base, _stm_nursery_start);
+ size = pseg->pub.nursery_current - (stm_char *)_stm_nursery_start;
memset(realnursery, 0, size);
- STM_SEGMENT->nursery_current = (stm_char *)_stm_nursery_start;
+ pseg->pub.nursery_current = (stm_char *)_stm_nursery_start;
/* free any object left from 'young_outside_nursery' */
- if (!tree_is_cleared(STM_PSEGMENT->young_outside_nursery)) {
+ if (!tree_is_cleared(pseg->young_outside_nursery)) {
bool locked = false;
wlog_t *item;
- TREE_LOOP_FORWARD(*STM_PSEGMENT->young_outside_nursery, item) {
+ TREE_LOOP_FORWARD(*pseg->young_outside_nursery, item) {
assert(!_is_in_nursery((object_t *)item->addr));
if (!locked) {
mutex_pages_lock();
locked = true;
}
- char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base,item->addr);
+ char *realobj = REAL_ADDRESS(pseg->pub.segment_base, item->addr);
ssize_t size = stmcb_size_rounded_up((struct object_s *)realobj);
increment_total_allocated(-(size + LARGE_MALLOC_OVERHEAD));
_stm_large_free(stm_object_pages + item->addr);
@@ -227,7 +227,7 @@
if (locked)
mutex_pages_unlock();
- tree_clear(STM_PSEGMENT->young_outside_nursery);
+ tree_clear(pseg->young_outside_nursery);
}
}
@@ -277,7 +277,7 @@
collect_oldrefs_to_nursery();
- throw_away_nursery();
+ throw_away_nursery(get_priv_segment(STM_SEGMENT->segment_num));
assert(MINOR_NOTHING_TO_DO(STM_PSEGMENT));
assert(list_is_empty(STM_PSEGMENT->objects_pointing_to_nursery));
@@ -405,6 +405,10 @@
_do_minor_collection(/*commit=*/ false);
assert(MINOR_NOTHING_TO_DO(pseg));
}
+ else {
+ dprintf(("abort data structures\n"));
+ abort_data_structures_from_segment_num(i);
+ }
}
set_gs_register(get_segment_base(original_num));
diff --git a/c7/stm/nursery.h b/c7/stm/nursery.h
--- a/c7/stm/nursery.h
+++ b/c7/stm/nursery.h
@@ -11,7 +11,7 @@
static void minor_collection(bool commit);
static void check_nursery_at_transaction_start(void);
-static void throw_away_nursery(void);
+static void throw_away_nursery(struct stm_priv_segment_info_s *pseg);
static void major_do_minor_collections(void);
static inline bool must_abort(void) {
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit