[pypy-commit] stmgc default: add mem_reset_on_abort, a mechanism to reset some memory to the value it had on

Raemi pypy.commits at gmail.com
Wed Apr 6 08:16:34 EDT 2016


Author: Remi Meier <remi.meier at gmail.com>
Branch: 
Changeset: r1985:ff3079618aaf
Date: 2016-04-06 15:16 +0300
http://bitbucket.org/pypy/stmgc/changeset/ff3079618aaf/

Log:	add mem_reset_on_abort, a mechanism to reset some memory to the
	value it had on tx start in case the tx aborts.

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1033,6 +1033,13 @@
 
     check_nursery_at_transaction_start();
 
+    if (tl->mem_reset_on_abort) {
+        assert(!!tl->mem_stored_for_reset_on_abort);
+        memcpy(tl->mem_stored_for_reset_on_abort, tl->mem_reset_on_abort,
+               tl->mem_bytes_to_reset_on_abort);
+    }
+
+
     /* Change read-version here, because if we do stm_validate in the
        safe-point below, we should not see our old reads from the last
        transaction. */
@@ -1432,6 +1439,9 @@
 
     if (tl->mem_clear_on_abort)
         memset(tl->mem_clear_on_abort, 0, tl->mem_bytes_to_clear_on_abort);
+    if (tl->mem_reset_on_abort)
+        memcpy(tl->mem_reset_on_abort, tl->mem_stored_for_reset_on_abort,
+               tl->mem_bytes_to_reset_on_abort);
 
     invoke_and_clear_user_callbacks(1);   /* for abort */
 
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -76,6 +76,11 @@
        the following raw region of memory is cleared. */
     char *mem_clear_on_abort;
     size_t mem_bytes_to_clear_on_abort;
+    /* mechanism to reset a memory location to the value it had at the start
+       of the transaction in case of an abort */
+    char *mem_reset_on_abort;   /* addr */
+    size_t mem_bytes_to_reset_on_abort; /* how many bytes */
+    char *mem_stored_for_reset_on_abort; /* content at tx start */
     /* the next fields are handled internally by the library */
     int last_associated_segment_num;   /* always a valid seg num */
     int thread_local_counter;
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -30,6 +30,9 @@
     object_t *thread_local_obj;
     char *mem_clear_on_abort;
     size_t mem_bytes_to_clear_on_abort;
+    char *mem_reset_on_abort;   /* addr */
+    size_t mem_bytes_to_reset_on_abort; /* how many bytes */
+    char *mem_stored_for_reset_on_abort; /* content at tx start */
     int last_associated_segment_num;
     struct stm_thread_local_s *prev, *next;
     void *creating_pthread[2];
diff --git a/c8/test/test_extra.py b/c8/test/test_extra.py
--- a/c8/test/test_extra.py
+++ b/c8/test/test_extra.py
@@ -19,6 +19,10 @@
         tl.mem_bytes_to_clear_on_abort = 2
         #
         self.start_transaction()
+        self.commit_transaction()
+        assert ffi.string(p) == "hello"
+        #
+        self.start_transaction()
         assert ffi.string(p) == "hello"
         self.abort_transaction()
         assert p[0] == '\0'
@@ -27,6 +31,27 @@
         assert p[3] == 'l'
         assert p[4] == 'o'
 
+    def test_reset_on_abort(self):
+        p = ffi.new("char[]", "hello")
+        tl = self.get_stm_thread_local()
+        assert tl.mem_reset_on_abort == ffi.NULL
+        tl.mem_reset_on_abort = p
+        tl.mem_bytes_to_reset_on_abort = 2
+        tl.mem_stored_for_reset_on_abort = ffi.new("char[5]")
+        #
+        self.start_transaction()
+        assert ffi.string(p) == "hello"
+        p[0] = 'w'
+        self.commit_transaction()
+        assert ffi.string(p) == "wello"
+        #
+        self.start_transaction()
+        assert ffi.string(p) == "wello"
+        p[1] = 'a'
+        p[4] = 'i'
+        self.abort_transaction()
+        assert ffi.string(p) == "welli"
+
     def test_call_on_abort(self):
         p0 = ffi_new_aligned("aaa")
         p1 = ffi_new_aligned("hello")


More information about the pypy-commit mailing list