[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