Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit