[pypy-commit] stmgc c7-refactor: Enough to pass the first test.

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


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

Log:	Enough to pass the first test.

diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -70,3 +70,5 @@
     return (struct stm_priv_segment_info_s *)REAL_ADDRESS(
         get_segment_base(segment_num), STM_PSEGMENT);
 }
+
+static bool _is_tl_registered(stm_thread_local_t *tl);
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -90,7 +90,7 @@
         stm_thread_locals->prev->next = tl;
         stm_thread_locals->prev = tl;
     }
-    tl->associated_segment_num = -1;
+    tl->associated_segment_num = NB_SEGMENTS;
 }
 
 void stm_unregister_thread_local(stm_thread_local_t *tl)
@@ -106,5 +106,9 @@
     tl->next->prev = tl->prev;
     tl->prev = NULL;
     tl->next = NULL;
-    tl->associated_segment_num = -1;
 }
+
+static bool _is_tl_registered(stm_thread_local_t *tl)
+{
+    return tl->next != NULL;
+}
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -7,7 +7,7 @@
 static union {
     struct {
         sem_t semaphore;
-        uint8_t in_use[NB_SEGMENTS];   /* 1 if running a pthread */
+        uint8_t in_use[NB_SEGMENTS + 1];   /* 1 if running a pthread */
     };
     char reserved[64];
 } segments_ctl __attribute__((aligned(64)));
@@ -16,6 +16,7 @@
 static void setup_sync(void)
 {
     memset(segments_ctl.in_use, 0, sizeof(segments_ctl.in_use));
+    segments_ctl.in_use[NB_SEGMENTS] = 0xff;
     if (sem_init(&segments_ctl.semaphore, 0, NB_SEGMENTS) != 0) {
         perror("sem_init");
         abort();
@@ -48,13 +49,12 @@
             abort();
         }
     }
+    assert(_is_tl_registered(tl));
     int num = tl->associated_segment_num;
-    if (num >= 0) {
-        if (__sync_lock_test_and_set(&segments_ctl.in_use[num], 1) == 0) {
-            /* fast-path: reacquired the same segment number than the one
-               we had.  The value stored in GS is still valid. */
-            goto exit;
-        }
+    if (__sync_lock_test_and_set(&segments_ctl.in_use[num], 1) == 0) {
+        /* fast-path: reacquired the same segment number than the one
+           we had before.  The value stored in GS is still valid. */
+        goto exit;
     }
     /* Look for the next free segment.  There must be one, because we
        acquired the semaphore above. */
@@ -85,3 +85,21 @@
 {
     return STM_SEGMENT->running_thread != NULL;
 }
+
+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_SEGMENT->running_thread == tl);
+}
+
+void stm_start_safe_point(int flags)
+{
+    //...
+}
+
+void stm_stop_safe_point(int flags)
+{
+    //...
+}
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -72,6 +72,7 @@
 bool _stm_in_transaction(void);
 char *_stm_real_address(object_t *o);
 object_t *_stm_segment_address(char *ptr);
+void _stm_test_switch(stm_thread_local_t *tl);
 #endif
 
 #define _STM_GCFLAG_WRITE_BARRIER  0x01
@@ -160,6 +161,8 @@
         _stm_become_inevitable(msg);
 }
 
+void stm_start_safe_point(int flags);
+void stm_stop_safe_point(int flags);
 
 /* ==================== END ==================== */
 
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -53,6 +53,7 @@
 char *_stm_real_address(object_t *obj);
 object_t *_stm_segment_address(char *ptr);
 bool _stm_in_transaction(void);
+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);
@@ -61,6 +62,13 @@
 
 void _set_type_id(object_t *obj, uint32_t h);
 uint32_t _get_type_id(object_t *obj);
+
+#define LOCK_COLLECT   ...
+#define LOCK_EXCLUSIVE ...
+#define THREAD_YIELD   ...
+
+void stm_start_safe_point(int);
+bool _check_stop_safe_point(int);
 """)
 
 
@@ -70,10 +78,6 @@
 void stm_abort_transaction(void);
 void stm_become_inevitable(char* msg);
 
-void _stm_start_safe_point(uint8_t);
-void _stm_stop_safe_point(uint8_t);
-bool _stm_check_stop_safe_point(void);
-
 void stm_push_root(object_t *obj);
 object_t *stm_pop_root(void);
 
@@ -102,13 +106,6 @@
     GCFLAG_MOVED = 4,
 };
 
-enum {
-    LOCK_COLLECT = 1,
-    LOCK_EXCLUSIVE = 2,
-    THREAD_YIELD = 4,
-};
-
-
 void stm_largemalloc_init(char *data_start, size_t data_size);
 int stm_largemalloc_resize_arena(size_t new_size);
 
@@ -141,6 +138,12 @@
 typedef TLPREFIX struct myobj_s myobj_t;
 #define SIZEOF_MYOBJ sizeof(struct myobj_s)
 
+enum {
+    LOCK_COLLECT = 1,
+    LOCK_EXCLUSIVE = 2,
+    THREAD_YIELD = 4,
+};
+
 
 uint8_t _stm_get_flags(object_t *obj) {
     return obj->stm_flags;
@@ -190,21 +193,23 @@
     _stm_dbg_get_tl(tn)->jmpbufptr = (jmpbufptr_t*)-1;
     return 1;
 }
+#endif
 
-bool _stm_check_stop_safe_point(void) {
-    jmpbufptr_t here;
-    int tn = _STM_TL->thread_num;
+bool _check_stop_safe_point(int flags) {
+    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;
-         _stm_stop_safe_point(LOCK_COLLECT);
-         _STM_TL->jmpbufptr = (jmpbufptr_t*)-1;
+         assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
+         segment->jmpbuf_ptr = &here;
+         stm_stop_safe_point(flags);
+         segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
          return 0;
     }
-    _stm_dbg_get_tl(tn)->jmpbufptr = (jmpbufptr_t*)-1;
+    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
     return 1;
 }
 
+#if 0
 bool _stm_check_abort_transaction(void) {
     jmpbufptr_t here;
     int tn = _STM_TL->thread_num;
@@ -369,10 +374,10 @@
 
 
 def stm_start_safe_point():
-    lib._stm_start_safe_point(lib.LOCK_COLLECT)
+    lib.stm_start_safe_point(lib.LOCK_COLLECT)
 
 def stm_stop_safe_point():
-    if lib._stm_check_stop_safe_point():
+    if lib._check_stop_safe_point(lib.LOCK_COLLECT):
         raise Conflict()
 
 def stm_become_inevitable():
@@ -412,7 +417,8 @@
 
     def teardown_method(self, meth):
         for n in sorted(self.running_transaction):
-            self.switch(n)
+            if self.current_thread != n:
+                self.switch(n)
             self.abort_transaction()
         for tl in self.tls:
             lib.stm_unregister_thread_local(tl)
@@ -432,8 +438,7 @@
         if tr:
             stm_start_safe_point()
         self.current_thread = thread_num
-        lib._stm_restore_local_state(thread_num)
-        tr = lib._stm_in_transaction()
-        assert tr == (self.current_thread in self.running_transaction)
-        if tr:
+        if thread_num in self.running_transaction:
+            tl = self.tls[thread_num]
+            lib._stm_test_switch(tl)
             stm_stop_safe_point() # can raise Conflict
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
@@ -18,7 +18,7 @@
         assert p3 - stm_get_real_address(lp2) == 16
         #
         self.switch(1)
-        stm_start_transaction()
+        self.start_transaction()
         lp1s = stm_allocate(16)
         assert is_in_nursery(lp1s)
         assert abs(stm_get_real_address(lp1s) - p3) >= 4000


More information about the pypy-commit mailing list