[pypy-commit] stmgc c7-refactor: in-progress

arigo noreply at buildbot.pypy.org
Mon Feb 10 19:50:17 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r723:77132519fe37
Date: 2014-02-10 19:47 +0100
http://bitbucket.org/pypy/stmgc/changeset/77132519fe37/

Log:	in-progress

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -53,3 +53,14 @@
     release_thread_segment(tl);
     abort();
 }
+
+void stm_abort_transaction(void)
+{
+    stm_thread_local_t *tl = STM_SEGMENT->running_thread;
+    stm_jmpbuf_t *jmpbuf_ptr = STM_SEGMENT->jmpbuf_ptr;
+    release_thread_segment(tl);
+
+    assert(jmpbuf_ptr != NULL);
+    assert(jmpbuf_ptr != (stm_jmpbuf_t *)-1);    /* for tests only */
+    __builtin_longjmp(*jmpbuf_ptr, 1);
+}
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -81,16 +81,19 @@
     sem_post(&segments_ctl.semaphore);
 }
 
-bool _stm_in_transaction(void)
+bool _stm_in_transaction(stm_thread_local_t *tl)
 {
-    return STM_SEGMENT->running_thread != NULL;
+    int num = tl->associated_segment_num;
+    if (num < NB_SEGMENTS)
+        return get_segment(num)->running_thread == tl;
+    else
+        return false;
 }
 
 void _stm_test_switch(stm_thread_local_t *tl)
 {
-    int num = tl->associated_segment_num;
-    assert(segments_ctl.in_use[num] == 1);
-    set_gs_register(get_segment_base(num));
+    assert(_stm_in_transaction(tl));
+    set_gs_register(get_segment_base(tl->associated_segment_num));
     assert(STM_SEGMENT->running_thread == tl);
 }
 
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -69,7 +69,7 @@
 bool _stm_was_read(object_t *obj);
 bool _stm_was_written(object_t *obj);
 bool _stm_in_nursery(object_t *obj);
-bool _stm_in_transaction(void);
+bool _stm_in_transaction(stm_thread_local_t *tl);
 char *_stm_real_address(object_t *o);
 object_t *_stm_segment_address(char *ptr);
 void _stm_test_switch(stm_thread_local_t *tl);
@@ -148,7 +148,7 @@
 void stm_start_transaction(stm_thread_local_t *tl, stm_jmpbuf_t *jmpbuf);
 void stm_start_inevitable_transaction(stm_thread_local_t *tl);
 void stm_commit_transaction(void);
-void stm_abort_transaction(void);
+void stm_abort_transaction(void) __attribute__((noreturn));
 
 #define STM_START_TRANSACTION(tl, jmpbuf)  ({           \
     int _restart = __builtin_setjmp(jmpbuf);            \
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -52,13 +52,15 @@
 bool _stm_in_nursery(object_t *obj);
 char *_stm_real_address(object_t *obj);
 object_t *_stm_segment_address(char *ptr);
-bool _stm_in_transaction(void);
+bool _stm_in_transaction(stm_thread_local_t *tl);
 void _stm_test_switch(stm_thread_local_t *tl);
 
 void stm_register_thread_local(stm_thread_local_t *tl);
 void stm_unregister_thread_local(stm_thread_local_t *tl);
 
 void stm_start_transaction(stm_thread_local_t *tl, stm_jmpbuf_t *jmpbuf);
+void stm_commit_transaction(void);
+bool _check_abort_transaction(void);
 
 void _set_type_id(object_t *obj, uint32_t h);
 uint32_t _get_type_id(object_t *obj);
@@ -74,8 +76,6 @@
 
 TEMPORARILY_DISABLED = """
 void stm_start_inevitable_transaction(stm_thread_local_t *tl);
-void stm_commit_transaction(void);
-void stm_abort_transaction(void);
 void stm_become_inevitable(char* msg);
 
 void stm_push_root(object_t *obj);
@@ -86,8 +86,6 @@
 
 void _stm_minor_collect();
 
-bool _stm_check_abort_transaction(void);
-
 void *memset(void *s, int c, size_t n);
 extern size_t stmcb_size(struct object_s *);
 extern void stmcb_trace(struct object_s *, void (object_t **));
@@ -126,6 +124,7 @@
 
 
 lib = ffi.verify('''
+#include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 
@@ -209,21 +208,19 @@
     return 1;
 }
 
-#if 0
-bool _stm_check_abort_transaction(void) {
-    jmpbufptr_t here;
-    int tn = _STM_TL->thread_num;
+int _check_abort_transaction(void) {
+    stm_jmpbuf_t here;
+    stm_segment_info_t *segment = STM_SEGMENT;
     if (__builtin_setjmp(here) == 0) { // returned directly
-         assert(_STM_TL->jmpbufptr == (jmpbufptr_t*)-1);
-         _STM_TL->jmpbufptr = &here;
+         assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
+         segment->jmpbuf_ptr = &here;
          stm_abort_transaction();
-         _stm_dbg_get_tl(tn)->jmpbufptr = (jmpbufptr_t*)-1;
-         return 0;
+         segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
+         return 0;   // but should be unreachable in this case
     }
-    _stm_dbg_get_tl(tn)->jmpbufptr = (jmpbufptr_t*)-1;
+    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
     return 1;
 }
-#endif
 
 
 void _set_type_id(object_t *obj, uint32_t h)
@@ -369,9 +366,6 @@
     if lib._stm_stop_transaction():
         raise Conflict()
 
-def stm_abort_transaction():
-    return lib._stm_check_abort_transaction()
-
 
 def stm_start_safe_point():
     lib.stm_start_safe_point(lib.LOCK_COLLECT)
@@ -413,32 +407,45 @@
         lib.stm_setup()
         self.tls = [_allocate_thread_local(), _allocate_thread_local()]
         self.current_thread = 0
-        self.running_transaction = set()
 
     def teardown_method(self, meth):
-        for n in sorted(self.running_transaction):
-            if self.current_thread != n:
-                self.switch(n)
-            self.abort_transaction()
+        for n, tl in enumerate(self.tls):
+            if lib._stm_in_transaction(tl):
+                if self.current_thread != n:
+                    self.switch(n)
+                self.abort_transaction()
         for tl in self.tls:
             lib.stm_unregister_thread_local(tl)
         lib.stm_teardown()
 
     def start_transaction(self):
-        n = self.current_thread
-        assert n not in self.running_transaction
-        tl = self.tls[n]
+        tl = self.tls[self.current_thread]
+        assert not lib._stm_in_transaction(tl)
         lib.stm_start_transaction(tl, ffi.cast("stm_jmpbuf_t *", -1))
-        self.running_transaction.add(n)
+        assert lib._stm_in_transaction(tl)
+
+    def commit_transaction(self):
+        tl = self.tls[self.current_thread]
+        assert lib._stm_in_transaction(tl)
+        lib.stm_commit_transaction()
+        assert not lib._stm_in_transaction(tl)
+
+    def abort_transaction(self):
+        tl = self.tls[self.current_thread]
+        assert lib._stm_in_transaction(tl)
+        res = lib._check_abort_transaction()
+        assert res   # abort_transaction() didn't abort!
+        assert not lib._stm_in_transaction(tl)
 
     def switch(self, thread_num):
-        tr = lib._stm_in_transaction()
-        assert tr == (self.current_thread in self.running_transaction)
         assert thread_num != self.current_thread
-        if tr:
+        tl = self.tls[self.current_thread]
+        if lib._stm_in_transaction(tl):
             stm_start_safe_point()
+        #
         self.current_thread = thread_num
-        if thread_num in self.running_transaction:
-            tl = self.tls[thread_num]
-            lib._stm_test_switch(tl)
+        tl2 = self.tls[thread_num]
+        #
+        if lib._stm_in_transaction(tl2):
+            lib._stm_test_switch(tl2)
             stm_stop_safe_point() # can raise Conflict


More information about the pypy-commit mailing list