[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