[pypy-commit] stmgc c8-gil-like: Minor tweaks to make life easier for the pypy jit

arigo noreply at buildbot.pypy.org
Sat Jun 13 16:47:10 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: c8-gil-like
Changeset: r1821:8009f12c327b
Date: 2015-06-13 16:47 +0200
http://bitbucket.org/pypy/stmgc/changeset/8009f12c327b/

Log:	Minor tweaks to make life easier for the pypy jit

diff --git a/c8/demo/demo_random2.c b/c8/demo/demo_random2.c
--- a/c8/demo/demo_random2.c
+++ b/c8/demo/demo_random2.c
@@ -365,7 +365,7 @@
     } else if (get_rand(20) == 1) {
         long pushed = push_roots();
         stm_become_inevitable(&stm_thread_local, "please");
-        assert(stm_is_inevitable());
+        assert(stm_is_inevitable(&stm_thread_local));
         pop_roots(pushed);
         p= NULL;
     } else if (get_rand(20) == 1) {
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1220,8 +1220,9 @@
 
 #ifdef STM_NO_AUTOMATIC_SETJMP
 void _test_run_abort(stm_thread_local_t *tl) __attribute__((noreturn));
-int stm_is_inevitable(void)
+int stm_is_inevitable(stm_thread_local_t *tl)
 {
+    assert(STM_SEGMENT->running_thread == tl);
     switch (STM_PSEGMENT->transaction_state) {
     case TS_REGULAR: return 0;
     case TS_INEVITABLE: return 1;
@@ -1593,7 +1594,7 @@
 
 void stm_stop_all_other_threads(void)
 {
-    if (!stm_is_inevitable())         /* may still abort */
+    if (!stm_is_inevitable(STM_SEGMENT->running_thread))  /* may still abort */
         _stm_become_inevitable("stop_all_other_threads");
 
     s_mutex_lock();
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -233,6 +233,8 @@
 {
     int num;
     s_mutex_lock();
+    tl->self = tl;    /* for faster access to &stm_thread_local (and easier
+                         from the PyPy JIT, too) */
     if (stm_all_thread_locals == NULL) {
         stm_all_thread_locals = tl->next = tl->prev = tl;
         num = 0;
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -71,7 +71,7 @@
     /* the next fields are handled internally by the library */
     int last_associated_segment_num;   /* always a valid seg num */
     int thread_local_counter;
-    struct stm_thread_local_s *prev, *next;
+    struct stm_thread_local_s *self, *prev, *next;
     void *creating_pthread[2];
 } stm_thread_local_t;
 
@@ -87,10 +87,10 @@
 long _stm_start_transaction(stm_thread_local_t *tl);
 void _stm_commit_transaction(void);
 void _stm_leave_noninevitable_transactional_zone(void);
-#define _stm_detach_inevitable_transaction(tl)  do {            \
-    write_fence();                                              \
-    assert(_stm_detached_inevitable_from_thread == 0);          \
-    _stm_detached_inevitable_from_thread = (intptr_t)(tl);      \
+#define _stm_detach_inevitable_transaction(tl)  do {                    \
+    write_fence();                                                      \
+    assert(_stm_detached_inevitable_from_thread == 0);                  \
+    _stm_detached_inevitable_from_thread = (intptr_t)(tl->self);        \
 } while (0)
 void _stm_reattach_transaction(stm_thread_local_t *tl);
 void _stm_become_inevitable(const char*);
@@ -391,10 +391,10 @@
 
 
 #ifdef STM_NO_AUTOMATIC_SETJMP
-int stm_is_inevitable(void);
+int stm_is_inevitable(stm_thread_local_t *tl);
 #else
-static inline int stm_is_inevitable(void) {
-    return !rewind_jmp_armed(&STM_SEGMENT->running_thread->rjthread);
+static inline int stm_is_inevitable(stm_thread_local_t *tl) {
+    return !rewind_jmp_armed(&tl->rjthread);
 }
 #endif
 
@@ -441,7 +441,7 @@
 }
 static inline void stm_leave_transactional_zone(stm_thread_local_t *tl) {
     assert(STM_SEGMENT->running_thread == tl);
-    if (stm_is_inevitable()) {
+    if (stm_is_inevitable(tl)) {
 #ifdef STM_DEBUGPRINT
         fprintf(stderr, "stm_leave_transactional_zone fast path\n");
 #endif
@@ -472,7 +472,7 @@
 static inline void stm_become_inevitable(stm_thread_local_t *tl,
                                          const char* msg) {
     assert(STM_SEGMENT->running_thread == tl);
-    if (!stm_is_inevitable())
+    if (!stm_is_inevitable(tl))
         _stm_become_inevitable(msg);
     /* now, we're running the inevitable transaction, so this var should be 0 */
     assert(_stm_detached_inevitable_from_thread == 0);
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -88,7 +88,7 @@
 //bool _check_become_globally_unique_transaction(stm_thread_local_t *tl);
 bool _check_stop_all_other_threads(void);
 void stm_resume_all_other_threads(void);
-int stm_is_inevitable(void);
+int stm_is_inevitable(stm_thread_local_t *);
 long current_segment_num(void);
 
 void _set_type_id(object_t *obj, uint32_t h);
@@ -770,14 +770,14 @@
         lib.stmcb_expand_marker = ffi.NULL
         lib.stmcb_debug_print = ffi.NULL
         tl = self.tls[self.current_thread]
-        if lib._stm_in_transaction(tl) and lib.stm_is_inevitable():
+        if lib._stm_in_transaction(tl) and self.is_inevitable():
             self.commit_transaction()      # must succeed!
         #
         for n, tl in enumerate(self.tls):
             if lib._stm_in_transaction(tl):
                 if self.current_thread != n:
                     self.switch(n)
-                if lib.stm_is_inevitable():
+                if self.is_inevitable():
                     self.commit_transaction()   # must succeed!
                 else:
                     self.abort_transaction()
@@ -786,6 +786,11 @@
             lib.stm_unregister_thread_local(tl)
         lib.stm_teardown()
 
+    def is_inevitable(self):
+        tl = self.tls[self.current_thread]
+        assert lib._stm_in_transaction(tl)
+        return lib.stm_is_inevitable(tl)
+
     def get_stm_thread_local(self):
         return self.tls[self.current_thread]
 
diff --git a/c8/test/test_basic.py b/c8/test/test_basic.py
--- a/c8/test/test_basic.py
+++ b/c8/test/test_basic.py
@@ -640,7 +640,7 @@
 
     def test_inevitable_transaction_has_priority(self):
         self.start_transaction()
-        assert lib.stm_is_inevitable() == 0
+        assert self.is_inevitable() == 0
         lp1 = stm_allocate(16)
         stm_set_char(lp1, 'a')
         self.push_root(lp1)
@@ -654,9 +654,9 @@
         self.start_transaction()
         stm_write(lp1)
         stm_set_char(lp1, 'b')
-        assert lib.stm_is_inevitable() == 0
+        assert self.is_inevitable() == 0
         self.become_inevitable()
-        assert lib.stm_is_inevitable() == 1
+        assert self.is_inevitable() == 1
         self.commit_transaction()
         #
         py.test.raises(Conflict, self.switch, 0)
diff --git a/c8/test/test_extra.py b/c8/test/test_extra.py
--- a/c8/test/test_extra.py
+++ b/c8/test/test_extra.py
@@ -189,7 +189,7 @@
         self.switch(1)
         self.start_transaction()
         self.become_globally_unique_transaction()
-        assert lib.stm_is_inevitable()
+        assert self.is_inevitable()
         #
         py.test.raises(Conflict, self.switch, 0)
 
@@ -199,7 +199,7 @@
         self.switch(1)
         self.start_transaction()
         self.stop_all_other_threads()
-        assert lib.stm_is_inevitable()
+        assert self.is_inevitable()
         #
         py.test.raises(Conflict, self.switch, 0)
         #
@@ -213,6 +213,6 @@
         self.start_transaction()
         self.stop_all_other_threads()
         self.resume_all_other_threads()
-        assert lib.stm_is_inevitable()
+        assert self.is_inevitable()
         #
         self.switch(0)   # no conflict


More information about the pypy-commit mailing list