Author: Remi Meier <[email protected]>
Branch: c8-private-pages
Changeset: r1563:670a3e29f448
Date: 2015-01-21 14:31 +0100
http://bitbucket.org/pypy/stmgc/changeset/670a3e29f448/

Log:    test for last commit

diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -315,11 +315,13 @@
 
 void stm_collect(long level)
 {
-    if (level > 0)
+    if (level > 0) {
         force_major_collection_request();
-
-    minor_collection(/*commit=*/ false);
-    major_collection_if_requested();
+        minor_collection(/*commit=*/ false);
+        major_collection_if_requested();
+    } else {
+        minor_collection(/*commit=*/ false);
+    }
 }
 
 
@@ -357,7 +359,11 @@
         /* use stm_collect() with level 0: if another thread does a major GC
            in-between, is_major_collection_requested() will become false
            again, and we'll avoid doing yet another one afterwards. */
+#ifndef STM_TESTS
+        /* during tests, we must not do a major collection during allocation.
+           The reason is that it may abort us and tests don't expect it. */
         stm_collect(0);
+#endif
     }
 
     object_t *o = (object_t *)allocate_outside_nursery_large(size_rounded_up);
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -80,7 +80,8 @@
 void _set_ptr(object_t *obj, int n, object_t *v);
 object_t * _get_ptr(object_t *obj, int n);
 
-void stm_collect(long level);
+/* void stm_collect(long level); */
+long _check_stm_collect(long level);
 uint64_t _stm_total_allocated(void);
 
 void _stm_set_nursery_free_count(uint64_t free_count);
@@ -175,6 +176,10 @@
     CHECKED(stm_commit_transaction());
 }
 
+bool _check_stm_collect(long level) {
+    CHECKED(stm_collect(level));
+}
+
 long _check_start_transaction(stm_thread_local_t *tl) {
    void **jmpbuf = tl->rjthread.jmpbuf;                         \
     if (__builtin_setjmp(jmpbuf) == 0) { /* returned directly */\
@@ -426,10 +431,13 @@
         raise Conflict()
 
 def stm_minor_collect():
-    lib.stm_collect(0)
+    assert not lib._check_stm_collect(0) # no conflict
 
 def stm_major_collect():
-    lib.stm_collect(1)
+    res = lib._check_stm_collect(1)
+    if res == 1:
+        raise Conflict()
+    return res
 
 def stm_is_accessible_page(pagenum):
     return lib._stm_is_accessible_page(pagenum)
diff --git a/c8/test/test_gcpage.py b/c8/test/test_gcpage.py
--- a/c8/test/test_gcpage.py
+++ b/c8/test/test_gcpage.py
@@ -393,3 +393,19 @@
         assert lib._stm_total_allocated() == 0
 
         self.commit_transaction()
+
+    def test_abort_thread_doing_major_gc(self):
+
+        o = stm_allocate_old(16)
+        self.start_transaction()
+        stm_set_char(o, 'a')
+
+        self.switch(1)
+        self.start_transaction()
+        stm_set_char(o, 'b')
+
+        self.switch(0)
+        self.commit_transaction()
+
+        self.switch(1, False)
+        py.test.raises(Conflict, stm_major_collect)
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
@@ -402,9 +402,19 @@
 
 def op_major_collect(ex, global_state, thread_state):
     thread_state.push_roots(ex)
-    ex.do('stm_major_collect()')
-    thread_state.pop_roots(ex)
-    thread_state.reload_roots(ex)
+
+    # check if we have to abort after the major gc
+    trs = thread_state.transaction_state
+    conflicts = trs.check_must_abort()
+    if conflicts:
+        ex.do("# objs_in_conflict=%s" % trs.objs_in_conflict)
+    ex.do(raising_call(conflicts, 'stm_major_collect'))
+
+    if conflicts:
+        thread_state.abort_transaction()
+    else:
+        thread_state.pop_roots(ex)
+        thread_state.reload_roots(ex)
 
 
 def op_forget_root(ex, global_state, thread_state):
@@ -497,7 +507,7 @@
 def op_switch_thread(ex, global_state, thread_state, new_thread_state=None):
     if new_thread_state is None:
         new_thread_state = global_state.rnd.choice(
-            global_state.thread_states + [thread_state] * 3) # more likely not 
switch
+            global_state.thread_states + [thread_state] * 10) # more likely 
not switch
 
     if new_thread_state != thread_state:
         if thread_state.transaction_state:
@@ -564,12 +574,12 @@
         possible_actions = [
             [op_read,]*100,
             [op_write,]*70,
-            [op_allocate,]*25,
-            [op_allocate_ref]*30,
-            [op_commit_transaction,]*10,
+            [op_allocate,]*10,
+            [op_allocate_ref]*10,
+            [op_commit_transaction,]*6,
             [op_abort_transaction,],
             [op_forget_root]*10,
-            [op_become_inevitable]*2,
+            [op_become_inevitable],
             [op_assert_size]*20,
             [op_assert_modified]*10,
             [op_minor_collect]*5,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to