Author: Remi Meier <[email protected]>
Branch:
Changeset: r1986:5e3551b4e599
Date: 2016-04-07 13:41 +0300
http://bitbucket.org/pypy/stmgc/changeset/5e3551b4e599/
Log: avoid data race with vmprof where *during* an abort a SIGPROF signal
gets handled and we already reset the thread-local.
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1063,7 +1063,7 @@
}
#ifdef STM_NO_AUTOMATIC_SETJMP
-static int did_abort = 0;
+int did_abort = 0;
#endif
long _stm_start_transaction(stm_thread_local_t *tl)
@@ -1075,6 +1075,12 @@
#else
long repeat_count = stm_rewind_jmp_setjmp(tl);
#endif
+ if (repeat_count) {
+ /* only if there was an abort, we need to reset the memory: */
+ 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);
+ }
_do_start_transaction(tl);
if (repeat_count == 0) { /* else, 'nursery_mark' was already set
@@ -1439,9 +1445,13 @@
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);
+ if (tl->mem_reset_on_abort) {
+ /* temporarily set the memory of mem_reset_on_abort to zeros since in
the
+ case of vmprof, the old value is really wrong if we didn't do the
longjmp
+ back yet (that restores the C stack). We restore the memory in
+ _stm_start_transaction() */
+ memset(tl->mem_reset_on_abort, 0, tl->mem_bytes_to_reset_on_abort);
+ }
invoke_and_clear_user_callbacks(1); /* for abort */
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -69,6 +69,10 @@
commit_log_root.rev_num = 0;
commit_log_root.written_count = 0;
+#ifdef STM_NO_AUTOMATIC_SETJMP
+ did_abort = 0;
+#endif
+
long i;
/* including seg0 */
for (i = 0; i < NB_SEGMENTS; i++) {
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -117,6 +117,11 @@
object_t *_stm_allocate_old(ssize_t size_rounded_up);
char *_stm_real_address(object_t *o);
#ifdef STM_TESTS
+
+#ifdef STM_NO_AUTOMATIC_SETJMP
+extern int did_abort;
+#endif
+
#include <stdbool.h>
uint8_t _stm_get_transaction_read_version(void);
uint8_t _stm_get_card_value(object_t *obj, long idx);
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
@@ -50,6 +50,8 @@
p[1] = 'a'
p[4] = 'i'
self.abort_transaction()
+ assert p[0] == '\0' # impl detail
+ self.start_transaction()
assert ffi.string(p) == "welli"
def test_call_on_abort(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit