Author: Armin Rigo <[email protected]>
Branch: c7-refactor
Changeset: r745:a221bc217ba9
Date: 2014-02-16 00:05 +0100
http://bitbucket.org/pypy/stmgc/changeset/a221bc217ba9/

Log:    Pass test_abort_cleanup.

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -238,6 +238,41 @@
     abort_with_mutex();
 }
 
+static void reset_modified_from_other_segments(void)
+{
+    /* pull the right versions from other threads in order
+       to reset our pages as part of an abort */
+    long remote_num = 1 - STM_SEGMENT->segment_num;
+    char *local_base = STM_SEGMENT->segment_base;
+    char *remote_base = get_segment_base(remote_num);
+
+    LIST_FOREACH_R(
+        STM_PSEGMENT->modified_objects,
+        object_t * /*item*/,
+        ({
+            /* memcpy in the opposite direction than
+               push_modified_to_other_segments() */
+            char *src = REAL_ADDRESS(remote_base, item);
+            ssize_t size = stmcb_size_rounded_up((struct object_s *)src);
+            memcpy(REAL_ADDRESS(local_base, item), src, size);
+
+            /* copying from the other thread re-added the
+               WRITE_BARRIER flag */
+            //assert(item->stm_flags & GCFLAG_WRITE_BARRIER);  --- XXX
+
+            /* write all changes to the object before we release the
+               write lock below */
+            write_fence();
+
+            /* clear the write-lock */
+            uintptr_t lock_idx = (((uintptr_t)item) >> 4) - READMARKER_START;
+            assert(write_locks[lock_idx]);
+            write_locks[lock_idx] = 0;
+        }));
+
+    list_clear(STM_PSEGMENT->modified_objects);
+}
+
 static void abort_with_mutex(void)
 {
     switch (STM_PSEGMENT->transaction_state) {
@@ -250,6 +285,9 @@
         assert(!"abort: bad transaction_state");
     }
 
+    /* reset all the modified objects (incl. re-adding GCFLAG_WRITE_BARRIER) */
+    reset_modified_from_other_segments();
+
     stm_jmpbuf_t *jmpbuf_ptr = STM_SEGMENT->jmpbuf_ptr;
     stm_thread_local_t *tl = STM_SEGMENT->running_thread;
     release_thread_segment(tl);   /* includes the cond_broadcast(); */
@@ -258,7 +296,6 @@
     mutex_unlock();
 
     reset_all_creation_markers();
-    list_clear(STM_PSEGMENT->modified_objects);
 
     assert(jmpbuf_ptr != NULL);
     assert(jmpbuf_ptr != (stm_jmpbuf_t *)-1);    /* for tests only */
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -60,7 +60,7 @@
 void _stm_test_switch(stm_thread_local_t *tl);
 
 void _stm_start_transaction(stm_thread_local_t *tl, stm_jmpbuf_t *jmpbuf);
-void stm_commit_transaction(void);
+bool _check_commit_transaction(void);
 bool _check_abort_transaction(void);
 
 void _set_type_id(object_t *obj, uint32_t h);
@@ -166,22 +166,6 @@
     return 1;
 }
 
-#if 0
-bool _stm_stop_transaction(void) {
-    jmpbufptr_t here;
-    int tn = _STM_TL->thread_num;
-    if (__builtin_setjmp(here) == 0) { // returned directly
-         assert(_STM_TL->jmpbufptr == (jmpbufptr_t*)-1);
-         _STM_TL->jmpbufptr = &here;
-         stm_stop_transaction();
-         _stm_dbg_get_tl(tn)->jmpbufptr = (jmpbufptr_t*)-1;
-         return 0;
-    }
-    _stm_dbg_get_tl(tn)->jmpbufptr = (jmpbufptr_t*)-1;
-    return 1;
-}
-#endif
-
 bool _check_stop_safe_point(void) {
     stm_jmpbuf_t here;
     stm_segment_info_t *segment = STM_SEGMENT;
@@ -196,7 +180,21 @@
     return 1;
 }
 
-int _check_abort_transaction(void) {
+bool _check_commit_transaction(void) {
+    stm_jmpbuf_t here;
+    stm_segment_info_t *segment = STM_SEGMENT;
+    if (__builtin_setjmp(here) == 0) { // returned directly
+         assert(segment->jmpbuf_ptr == (stm_jmpbuf_t *)-1);
+         segment->jmpbuf_ptr = &here;
+         stm_commit_transaction();
+         segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
+         return 0;
+    }
+    segment->jmpbuf_ptr = (stm_jmpbuf_t *)-1;
+    return 1;
+}
+
+bool _check_abort_transaction(void) {
     stm_jmpbuf_t here;
     stm_segment_info_t *segment = STM_SEGMENT;
     if (__builtin_setjmp(here) == 0) { // returned directly
@@ -422,8 +420,10 @@
     def commit_transaction(self):
         tl = self.tls[self.current_thread]
         assert lib._stm_in_transaction(tl)
-        lib.stm_commit_transaction()
+        res = lib._check_commit_transaction()
         assert not lib._stm_in_transaction(tl)
+        if res:
+            raise Conflict
 
     def abort_transaction(self):
         tl = self.tls[self.current_thread]
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
@@ -308,7 +308,7 @@
 
         self.start_transaction()
         stm_set_char(lp1, 'x')
-        assert stm_abort_transaction()
+        self.abort_transaction()
 
         self.start_transaction()
         assert stm_get_char(lp1) == 'a'
@@ -439,7 +439,7 @@
         self.push_root(new)
         stm_minor_collect()
         new = self.pop_root()
-        stm_abort_transaction()
+        self.abort_transaction()
 
         self.start_transaction()
         newer = stm_allocate(16)
@@ -456,7 +456,7 @@
         stm_minor_collect()
         new = self.pop_root()
         # assert stm_get_page_flag(stm_get_obj_pages(new)[0]) == 
lib.UNCOMMITTED_SHARED_PAGE
-        stm_abort_transaction()
+        self.abort_transaction()
 
         self.start_transaction()
         newer = stm_allocate(16)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to