Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r976:e596369e8a2d
Date: 2014-03-12 08:50 +0100
http://bitbucket.org/pypy/stmgc/changeset/e596369e8a2d/

Log:    stm_is_inevitable(), and fix tests for inevitable transactions

diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -248,6 +248,9 @@
     if (STM_SEGMENT->jmpbuf_ptr != NULL)
         _stm_become_inevitable(msg);
 }
+static inline int stm_is_inevitable(void) {
+    return (STM_SEGMENT->jmpbuf_ptr == NULL);
+}
 
 /* Forces a safe-point if needed.  Normally not needed: this is
    automatic if you call stm_allocate(). */
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -46,7 +46,8 @@
 void _stm_start_transaction(stm_thread_local_t *tl, stm_jmpbuf_t *jmpbuf);
 bool _check_commit_transaction(void);
 bool _check_abort_transaction(void);
-bool _check_become_inevitable();
+bool _check_become_inevitable(void);
+int stm_is_inevitable(void);
 
 void _set_type_id(object_t *obj, uint32_t h);
 uint32_t _get_type_id(object_t *obj);
@@ -110,76 +111,47 @@
     return obj->stm_flags;
 }
 
+#define CHECKED(CALL)                                           \
+    stm_jmpbuf_t here;                                          \
+    stm_segment_info_t *segment = STM_SEGMENT;                  \
+    if (__builtin_setjmp(here) == 0) { /* returned directly */  \
+        if (segment->jmpbuf_ptr != NULL) {                      \
+            assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);  \
+            segment->jmpbuf_ptr = &here;                        \
+        }                                                       \
+        CALL;                                                   \
+        if (segment->jmpbuf_ptr != NULL) {                      \
+            segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;           \
+        }                                                       \
+        return 0;                                               \
+    }                                                           \
+    if (segment->jmpbuf_ptr != NULL) {                          \
+        segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;               \
+    }                                                           \
+    return 1
+
 bool _checked_stm_write(object_t *object) {
-    stm_jmpbuf_t here;
-    stm_segment_info_t *segment = STM_SEGMENT;
-    if (__builtin_setjmp(here) == 0) { // returned directly
-        assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
-        segment->jmpbuf_ptr = &here;
-        stm_write(object);
-        segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-        return 0;
-    }
-    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-    return 1;
+    CHECKED(stm_write(object));
 }
 
 bool _check_stop_safe_point(void) {
-    stm_jmpbuf_t here;
-    stm_segment_info_t *segment = STM_SEGMENT;
-    if (__builtin_setjmp(here) == 0) { // returned directly
-         assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
-         segment->jmpbuf_ptr = &here;
-         _stm_stop_safe_point();
-         segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-         return 0;
-    }
-    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-    return 1;
+    CHECKED(_stm_stop_safe_point());
 }
 
 bool _check_commit_transaction(void) {
-    stm_jmpbuf_t here;
-    stm_segment_info_t *segment = STM_SEGMENT;
-    if (__builtin_setjmp(here) == 0) { // returned directly
-         assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
-         segment->jmpbuf_ptr = &here;
-         stm_commit_transaction();
-         segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-         return 0;
-    }
-    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-    return 1;
+    CHECKED(stm_commit_transaction());
 }
 
 bool _check_abort_transaction(void) {
-    stm_jmpbuf_t here;
-    stm_segment_info_t *segment = STM_SEGMENT;
-    if (__builtin_setjmp(here) == 0) { // returned directly
-         assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
-         segment->jmpbuf_ptr = &here;
-         stm_abort_transaction();
-         segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-         return 0;   // but should be unreachable in this case
-    }
-    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-    return 1;
+    CHECKED(stm_abort_transaction());
 }
 
 bool _check_become_inevitable() {
-    stm_jmpbuf_t here;
-    stm_segment_info_t *segment = STM_SEGMENT;
-    if (__builtin_setjmp(here) == 0) { // returned directly
-         assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
-         segment->jmpbuf_ptr = &here;
-         stm_become_inevitable("TEST");
-         segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-         return 0;   // but should be unreachable in this case
-    }
-    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
-    return 1;
+    CHECKED(stm_become_inevitable("TEST"));
 }
 
+#undef CHECKED
+
 
 void _set_type_id(object_t *obj, uint32_t h)
 {
diff --git a/c7/test/test_basic.py b/c7/test/test_basic.py
--- a/c7/test/test_basic.py
+++ b/c7/test/test_basic.py
@@ -382,7 +382,9 @@
         self.start_transaction()
         stm_write(lp1)
         stm_set_char(lp1, 'b')
+        assert lib.stm_is_inevitable() == 0
         stm_become_inevitable()
+        assert lib.stm_is_inevitable() == 1
         self.commit_transaction()
         #
         py.test.raises(Conflict, self.switch, 0)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to