[pypy-commit] stmgc c8-new-page-handling: actually *do* apply undo copies if we abort

Raemi noreply at buildbot.pypy.org
Mon Sep 29 16:08:56 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-new-page-handling
Changeset: r1436:14164f0fc6a8
Date: 2014-09-29 16:09 +0200
http://bitbucket.org/pypy/stmgc/changeset/14164f0fc6a8/

Log:	actually *do* apply undo copies if we abort

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -156,6 +156,8 @@
     release_modified_objs_lock(copy_from_segnum);
     release_all_privatization_locks();
 
+    dprintf(("handle_segfault_in_page: rev %lu to rev %lu\n",
+             src_version->rev_num, target_version->rev_num));
     /* adapt revision of page to our revision:
        if our rev is higher than the page we copy from, everything
        is fine as we never read/modified the page anyway
@@ -217,9 +219,9 @@
         for (; undo < end; undo++) {
             fprintf(stderr, "    obj %p, size %d, ofs %lu: ", undo->object,
                     SLICE_SIZE(undo->slice), SLICE_OFFSET(undo->slice));
-            long i;
-            for (i=0; i<SLICE_SIZE(undo->slice); i += 8)
-                fprintf(stderr, " 0x%016lx", *(long *)(undo->backup + i));
+            /* long i; */
+            /* for (i=0; i<SLICE_SIZE(undo->slice); i += 8) */
+            /*     fprintf(stderr, " 0x%016lx", *(long *)(undo->backup + i)); */
             fprintf(stderr, "\n");
         }
     }
@@ -258,9 +260,8 @@
             /* there is an inevitable transaction running */
             release_modified_objs_lock(my_segnum);
 #if STM_TESTS
-            if (free_if_abort != (void *)-1)
-                free(free_if_abort);
-            stm_abort_transaction();
+            needs_abort = true;
+            goto complete_work_and_possibly_abort;
 #endif
             abort();  /* XXX non-busy wait here
                          or: XXX do we always need to wait?  we should just
@@ -310,6 +311,9 @@
 
     release_modified_objs_lock(my_segnum);
 
+#if STM_TESTS
+ complete_work_and_possibly_abort:;
+#endif
     /* XXXXXXXXXXXXXXXX CORRECT LOCKING NEEDED XXXXXXXXXXXXXXXXXXXXXX */
     int segnum;
     for (segnum = 0; segment_copied_from != 0; segnum++) {
@@ -317,8 +321,10 @@
             segment_copied_from &= ~(1UL << segnum);
             /* here we can actually have our own modified version, so
                make sure to only copy things that are not modified in our
-               segment... */
-            copy_bk_objs_in_page_from(segnum, -1, true);
+               segment... (if we do not abort) */
+            copy_bk_objs_in_page_from(
+                segnum, -1,     /* any page */
+                !needs_abort);  /* if we abort, we still want to copy everything */
         }
     }
 
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
@@ -783,3 +783,30 @@
         #
         self.switch(0) # validate -> R2
         assert stm_get_char(lp_char_5, 384 - 1) == 'i'
+
+    def test_bug2(self):
+        lp_char_5 = stm_allocate_old(384)
+
+        self.start_transaction() # R1
+        stm_set_char(lp_char_5, 'i', 384 - 1, False)
+        stm_set_char(lp_char_5, 'i', HDR, False)
+        #
+        self.switch(1)
+        self.start_transaction()
+        #
+        #
+        self.switch(3)
+        self.start_transaction()  # R1
+        stm_set_char(lp_char_5, 'o', 384 - 1, False) # bk_copy
+        stm_set_char(lp_char_5, 'o', HDR, False)
+        self.commit_transaction() # R2
+
+        self.start_transaction()  # R2
+        stm_set_char(lp_char_5, 'r', 384 - 1, False) # bk_copy
+        stm_set_char(lp_char_5, 'r', HDR, False)
+        #
+        py.test.raises(Conflict, self.switch, 0) # abort modified objs
+        #
+        self.switch(1) # validate -> R2
+
+        assert stm_get_char(lp_char_5, 384 - 1) == 'o'
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
@@ -298,6 +298,7 @@
 
             confl_set = other_trs.read_set & trs.write_set
             if confl_set:
+                assert not other_trs.inevitable
                 # trs wins!
                 other_trs.set_must_abort(objs_in_conflict=confl_set)
                 assert not trs.check_must_abort()
@@ -506,14 +507,16 @@
         ex.do('#')
         #
         trs = new_thread_state.transaction_state
-        if trs is not None and not trs.inevitable:
-            if global_state.is_inevitable_transaction_running():
-                trs.set_must_abort()
-        conflicts = trs is not None and trs.check_must_abort()
+        if trs and not trs.check_must_abort():
+            global_state.check_if_can_become_inevitable(trs)
+        conflicts = trs and trs.check_must_abort()
         ex.thread_num = new_thread_state.num
         #
+        if conflicts:
+            ex.do("# objs_in_conflict=%s" % trs.objs_in_conflict)
         ex.do(raising_call(conflicts,
                            "self.switch", new_thread_state.num))
+
         if conflicts:
             new_thread_state.abort_transaction()
         elif trs:


More information about the pypy-commit mailing list