[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