[pypy-commit] stmgc default: Finish the hopefully-correct attribution of times in contention. More tests.
arigo
noreply at buildbot.pypy.org
Sun Mar 30 19:58:49 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r1121:f7a1890045b3
Date: 2014-03-30 19:58 +0200
http://bitbucket.org/pypy/stmgc/changeset/f7a1890045b3/
Log: Finish the hopefully-correct attribution of times in contention.
More tests.
diff --git a/c7/stm/contention.c b/c7/stm/contention.c
--- a/c7/stm/contention.c
+++ b/c7/stm/contention.c
@@ -122,8 +122,8 @@
#endif
/* Fix the choices that are found incorrect due to TS_INEVITABLE
- or NSE_SIGABORT */
- if (contmgr.other_pseg->pub.nursery_end == NSE_SIGABORT) {
+ or is_abort() */
+ if (is_abort(contmgr.other_pseg->pub.nursery_end)) {
contmgr.abort_other = true;
contmgr.try_sleep = false;
}
@@ -136,6 +136,19 @@
contmgr.abort_other = false;
}
+
+ int wait_category =
+ kind == WRITE_READ_CONTENTION ? STM_TIME_WAIT_WRITE_READ :
+ kind == INEVITABLE_CONTENTION ? STM_TIME_WAIT_INEVITABLE :
+ STM_TIME_WAIT_OTHER;
+
+ int abort_category =
+ kind == WRITE_WRITE_CONTENTION ? STM_TIME_RUN_ABORTED_WRITE_WRITE :
+ kind == WRITE_READ_CONTENTION ? STM_TIME_RUN_ABORTED_WRITE_READ :
+ kind == INEVITABLE_CONTENTION ? STM_TIME_RUN_ABORTED_INEVITABLE :
+ STM_TIME_RUN_ABORTED_OTHER;
+
+
if (contmgr.try_sleep && kind != WRITE_WRITE_CONTENTION &&
contmgr.other_pseg->safe_point != SP_WAIT_FOR_C_TRANSACTION_DONE) {
/* Sleep.
@@ -149,6 +162,8 @@
*/
contmgr.other_pseg->signal_when_done = true;
+ change_timing_state(wait_category);
+
/* XXX should also tell other_pseg "please commit soon" */
dprintf(("pausing...\n"));
@@ -160,15 +175,20 @@
if (must_abort())
abort_with_mutex();
+
+ change_timing_state(STM_TIME_RUN_CURRENT);
}
+
else if (!contmgr.abort_other) {
dprintf(("abort in contention\n"));
+ STM_SEGMENT->nursery_end = abort_category;
abort_with_mutex();
}
+
else {
/* We have to signal the other thread to abort, and wait until
it does. */
- contmgr.other_pseg->pub.nursery_end = NSE_SIGABORT;
+ contmgr.other_pseg->pub.nursery_end = abort_category;
int sp = contmgr.other_pseg->safe_point;
switch (sp) {
diff --git a/c7/stm/contention.h b/c7/stm/contention.h
--- a/c7/stm/contention.h
+++ b/c7/stm/contention.h
@@ -3,7 +3,11 @@
static void write_read_contention_management(uint8_t other_segment_num);
static void inevitable_contention_management(uint8_t other_segment_num);
+static inline bool is_abort(uintptr_t nursery_end) {
+ return (nursery_end <= _STM_NSE_SIGNAL_MAX && nursery_end != NSE_SIGPAUSE);
+}
+
static inline bool is_aborting_now(uint8_t other_segment_num) {
- return (get_segment(other_segment_num)->nursery_end == NSE_SIGABORT &&
+ return (is_abort(get_segment(other_segment_num)->nursery_end) &&
get_priv_segment(other_segment_num)->safe_point != SP_RUNNING);
}
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -435,7 +435,7 @@
list_clear(STM_PSEGMENT->modified_old_objects);
}
-static void _finish_transaction(enum stm_time_e attribute_to)
+static void _finish_transaction(int attribute_to)
{
STM_PSEGMENT->safe_point = SP_NO_TRANSACTION;
STM_PSEGMENT->transaction_state = TS_NONE;
@@ -636,13 +636,16 @@
/* invoke the callbacks */
invoke_and_clear_callbacks_on_abort();
- if (STM_SEGMENT->nursery_end == NSE_SIGABORT) {
+ int attribute_to = STM_TIME_RUN_ABORTED_OTHER;
+
+ if (is_abort(STM_SEGMENT->nursery_end)) {
/* done aborting */
+ attribute_to = STM_SEGMENT->nursery_end;
STM_SEGMENT->nursery_end = pause_signalled ? NSE_SIGPAUSE
: NURSERY_END;
}
- _finish_transaction(STM_TIME_RUN_ABORTED_OTHER);
+ _finish_transaction(attribute_to);
/* cannot access STM_SEGMENT or STM_PSEGMENT from here ! */
/* Broadcast C_ABORTED to wake up contention.c */
diff --git a/c7/stm/nursery.h b/c7/stm/nursery.h
--- a/c7/stm/nursery.h
+++ b/c7/stm/nursery.h
@@ -1,10 +1,6 @@
/* '_stm_nursery_section_end' is either NURSERY_END or NSE_SIGxxx */
-#define NSE_SIGPAUSE 0
-#define NSE_SIGABORT 1
-#if NSE_SIGABORT > _STM_NSE_SIGNAL_MAX
-# error "update _STM_NSE_SIGNAL_MAX"
-#endif
+#define NSE_SIGPAUSE STM_TIME_WAIT_OTHER
static uint32_t highest_overflow_number;
@@ -14,9 +10,7 @@
static size_t throw_away_nursery(struct stm_priv_segment_info_s *pseg);
static void major_do_minor_collections(void);
-static inline bool must_abort(void) {
- return STM_SEGMENT->nursery_end == NSE_SIGABORT;
-}
+#define must_abort() is_abort(STM_SEGMENT->nursery_end)
static void assert_memset_zero(void *s, size_t n);
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -63,9 +63,9 @@
STM_TIME_RUN_ABORTED_INEVITABLE,
STM_TIME_RUN_ABORTED_OTHER,
STM_TIME_WAIT_FREE_SEGMENT,
- STM_TIME_WAIT_WRITE_WRITE,
STM_TIME_WAIT_WRITE_READ,
STM_TIME_WAIT_INEVITABLE,
+ STM_TIME_WAIT_OTHER,
STM_TIME_BOOKKEEPING,
STM_TIME_MINOR_GC,
STM_TIME_MAJOR_GC,
@@ -136,7 +136,7 @@
#endif
#define _STM_GCFLAG_WRITE_BARRIER 0x01
-#define _STM_NSE_SIGNAL_MAX 1
+#define _STM_NSE_SIGNAL_MAX _STM_TIME_N
#define _STM_FAST_ALLOC (66*1024)
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -108,9 +108,9 @@
#define STM_TIME_RUN_ABORTED_INEVITABLE ...
#define STM_TIME_RUN_ABORTED_OTHER ...
#define STM_TIME_WAIT_FREE_SEGMENT ...
-#define STM_TIME_WAIT_WRITE_WRITE ...
#define STM_TIME_WAIT_WRITE_READ ...
#define STM_TIME_WAIT_INEVITABLE ...
+#define STM_TIME_WAIT_OTHER ...
#define STM_TIME_BOOKKEEPING ...
#define STM_TIME_MINOR_GC ...
#define STM_TIME_MAJOR_GC ...
diff --git a/c7/test/test_timing.py b/c7/test/test_timing.py
--- a/c7/test/test_timing.py
+++ b/c7/test/test_timing.py
@@ -12,7 +12,12 @@
def expect_timer(self, n, expected_value):
real = self.gettimer(n)
print 'timer %d is %s, expecting %s' % (n, real, expected_value)
- assert abs(real - expected_value) < 0.09
+ if expected_value == 0.0:
+ assert real == 0.0
+ elif expected_value == "nonzero":
+ assert real > 0.0
+ else:
+ assert abs(real - expected_value) < 0.09
def test_time_outside_transaction(self):
time.sleep(0.2)
@@ -35,3 +40,55 @@
self.expect_timer(lib.STM_TIME_RUN_COMMITTED, 0.0)
self.commit_transaction()
self.expect_timer(lib.STM_TIME_RUN_COMMITTED, 0.2)
+
+ def test_time_run_aborted_write_write(self):
+ o = stm_allocate_old(16)
+ self.start_transaction()
+ stm_write(o)
+ #
+ self.switch(1)
+ self.start_transaction()
+ time.sleep(0.2)
+ py.test.raises(Conflict, stm_write, o)
+ self.expect_timer(lib.STM_TIME_RUN_ABORTED_WRITE_WRITE, 0.2)
+
+ def test_time_run_aborted_write_read(self):
+ o = stm_allocate_old(16)
+ self.start_transaction()
+ stm_read(o)
+ #
+ self.switch(1)
+ self.start_transaction()
+ time.sleep(0.2)
+ stm_write(o)
+ py.test.raises(Conflict, self.commit_transaction)
+ self.expect_timer(lib.STM_TIME_RUN_ABORTED_WRITE_READ, 0.2)
+
+ def test_time_run_aborted_inevitable(self):
+ self.start_transaction()
+ self.become_inevitable()
+ #
+ self.switch(1)
+ self.start_transaction()
+ time.sleep(0.2)
+ py.test.raises(Conflict, self.become_inevitable)
+ self.expect_timer(lib.STM_TIME_RUN_ABORTED_INEVITABLE, 0.2)
+
+ def test_time_run_aborted_other(self):
+ self.start_transaction()
+ time.sleep(0.2)
+ self.abort_transaction()
+ self.expect_timer(lib.STM_TIME_RUN_ABORTED_OTHER, 0.2)
+
+ def test_time_minor_gc(self):
+ self.start_transaction()
+ self.expect_timer(lib.STM_TIME_MINOR_GC, 0.0)
+ stm_minor_collect()
+ self.expect_timer(lib.STM_TIME_MINOR_GC, "nonzero")
+ self.expect_timer(lib.STM_TIME_MAJOR_GC, 0.0)
+
+ def test_time_major_gc(self):
+ self.start_transaction()
+ self.expect_timer(lib.STM_TIME_MAJOR_GC, 0.0)
+ stm_major_collect()
+ self.expect_timer(lib.STM_TIME_MAJOR_GC, "nonzero")
More information about the pypy-commit
mailing list