[pypy-commit] stmgc c8-new-page-handling: check abort in signal handler

Raemi noreply at buildbot.pypy.org
Mon Sep 22 13:56:37 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-new-page-handling
Changeset: r1407:3779031defc6
Date: 2014-09-22 13:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/3779031defc6/

Log:	check abort in signal handler

diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -48,6 +48,7 @@
 void _stm_start_safe_point(void);
 bool _check_stop_safe_point(void);
 
+ssize_t _checked_stmcb_size_rounded_up(struct object_s *obj);
 
 bool _checked_stm_write(object_t *obj);
 bool _stm_was_read(object_t *obj);
@@ -166,6 +167,20 @@
     return 1;
 }
 
+ssize_t _checked_stmcb_size_rounded_up(struct object_s *obj)
+{
+    stm_thread_local_t *_tl = STM_SEGMENT->running_thread;      \
+    void **jmpbuf = _tl->rjthread.jmpbuf;                       \
+    if (__builtin_setjmp(jmpbuf) == 0) { /* returned directly */\
+        ssize_t res = stmcb_size_rounded_up(obj);
+        clear_jmpbuf(_tl);
+        return res;
+    }
+    clear_jmpbuf(_tl);
+    return 1;
+}
+
+
 bool _check_stop_safe_point(void) {
     CHECKED(_stm_stop_safe_point());
 }
@@ -396,7 +411,10 @@
     return lib._stm_get_private_page(pagenum)
 
 def stm_get_obj_size(o):
-    return lib.stmcb_size_rounded_up(stm_get_real_address(o))
+    res = lib._checked_stmcb_size_rounded_up(stm_get_real_address(o))
+    if res == 1:
+        raise Conflict()
+    return res
 
 def stm_get_obj_pages(o):
     start = int(ffi.cast('uintptr_t', o))
@@ -511,7 +529,7 @@
         assert res   # abort_transaction() didn't abort!
         assert not lib._stm_in_transaction(tl)
 
-    def switch(self, thread_num):
+    def switch(self, thread_num, validate=True):
         assert thread_num != self.current_thread
         tl = self.tls[self.current_thread]
         if lib._stm_in_transaction(tl):
@@ -523,7 +541,8 @@
         if lib._stm_in_transaction(tl2):
             lib._stm_test_switch(tl2)
             stm_stop_safe_point() # can raise Conflict
-            stm_validate() # can raise Conflict
+            if validate:
+                stm_validate() # can raise Conflict
 
     def switch_to_segment(self, seg_num):
         lib._stm_test_switch_segment(seg_num)
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
@@ -543,3 +543,34 @@
         assert self.get_stm_thread_local().last_abort__bytes_in_nursery == 56
         self.abort_transaction()
         assert self.get_stm_thread_local().last_abort__bytes_in_nursery == 0
+
+    def test_abort_in_segfault_handler(self):
+        lp1 = stm_allocate_old(16)
+        lp2 = stm_allocate_old(16)
+
+        self.start_transaction()
+        stm_set_char(lp1, 'A')
+        stm_set_char(lp2, 'B')
+        self.commit_transaction()
+        # lp1 = S|N|N|N
+        # lp2 = S|N|N|N
+
+        self.switch(1)
+
+        self.start_transaction()
+        assert stm_get_char(lp1) == 'A'
+        # lp1 = S|P|N|N
+        # lp2 = S|N|N|N
+
+        self.switch(0)
+
+        self.start_transaction()
+        stm_set_char(lp1, 'C')
+        self.commit_transaction()
+        # lp1 = S|P|N|N
+        # lp2 = S|N|N|N
+
+        self.switch(1, validate=False)
+
+        # seg1 segfaults, validates, and aborts:
+        py.test.raises(Conflict, stm_get_char, lp2)
diff --git a/c8/test/test_random.py b/c8/test/test_random.py
--- a/c8/test/test_random.py
+++ b/c8/test/test_random.py
@@ -535,7 +535,7 @@
     def test_fixed_16_bytes_objects(self, seed=1010):
         rnd = random.Random(seed)
 
-        N_OBJECTS = 3
+        N_OBJECTS = 4
         N_THREADS = self.NB_THREADS
         ex = Exec(self)
         ex.do("################################################################\n"*10)
@@ -575,7 +575,7 @@
             op_minor_collect,
             #op_major_collect,
         ]
-        for _ in range(200):
+        for _ in range(500):
             # make sure we are in a transaction:
             curr_thread = op_switch_thread(ex, global_state, curr_thread)
 


More information about the pypy-commit mailing list