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

Reply via email to