Author: Armin Rigo <[email protected]>
Branch: stmgc-c7-rewindjmp
Changeset: r72800:057a885fd864
Date: 2014-08-14 16:17 +0200
http://bitbucket.org/pypy/pypy/changeset/057a885fd864/

Log:    import stmgc/29376f500349

diff --git a/rpython/translator/stm/src_stm/revision 
b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-1815f493a1c5
+29376f500349
diff --git a/rpython/translator/stm/src_stm/stm/core.c 
b/rpython/translator/stm/src_stm/stm/core.c
--- a/rpython/translator/stm/src_stm/stm/core.c
+++ b/rpython/translator/stm/src_stm/stm/core.c
@@ -329,8 +329,6 @@
 {
     assert(!_stm_in_transaction(tl));
 
-    s_mutex_lock();
-
   retry:
     if (inevitable) {
         wait_for_end_of_inevitable_transaction(tl);
@@ -391,6 +389,7 @@
 
 long stm_start_transaction(stm_thread_local_t *tl)
 {
+    s_mutex_lock();
 #ifdef STM_NO_AUTOMATIC_SETJMP
     long repeat_count = 0;    /* test/support.py */
 #else
@@ -402,6 +401,7 @@
 
 void stm_start_inevitable_transaction(stm_thread_local_t *tl)
 {
+    s_mutex_lock();
     _stm_start_transaction(tl, true);
 }
 
@@ -998,7 +998,11 @@
     /* NB. careful, this function might be called more than once to
        abort a given segment.  Make sure that
        stm_rewind_jmp_restore_shadowstack() is idempotent. */
-    stm_rewind_jmp_restore_shadowstack(tl);
+    /* we need to do this here and not directly in rewind_longjmp() because
+       that is called when we already released everything (safe point)
+       and a concurrent major GC could mess things up. */
+    if (tl->shadowstack != NULL)
+        stm_rewind_jmp_restore_shadowstack(tl);
     assert(tl->shadowstack == pseg->shadowstack_at_start_of_transaction);
 #endif
     tl->thread_local_obj = pseg->threadlocal_at_start_of_transaction;
@@ -1025,7 +1029,7 @@
 }
 #endif
 
-static void abort_with_mutex(void)
+static stm_thread_local_t *abort_with_mutex_no_longjmp(void)
 {
     assert(_has_mutex());
     dprintf(("~~~ ABORT\n"));
@@ -1058,6 +1062,12 @@
     /* Broadcast C_ABORTED to wake up contention.c */
     cond_broadcast(C_ABORTED);
 
+    return tl;
+}
+
+static void abort_with_mutex(void)
+{
+    stm_thread_local_t *tl = abort_with_mutex_no_longjmp();
     s_mutex_unlock();
 
     /* It seems to be a good idea, at least in some examples, to sleep
@@ -1075,6 +1085,7 @@
 #ifdef STM_NO_AUTOMATIC_SETJMP
     _test_run_abort(tl);
 #else
+    s_mutex_lock();
     stm_rewind_jmp_longjmp(tl);
 #endif
 }
diff --git a/rpython/translator/stm/src_stm/stm/core.h 
b/rpython/translator/stm/src_stm/stm/core.h
--- a/rpython/translator/stm/src_stm/stm/core.h
+++ b/rpython/translator/stm/src_stm/stm/core.h
@@ -273,6 +273,7 @@
 
 static void teardown_core(void);
 static void abort_with_mutex(void) __attribute__((noreturn));
+static stm_thread_local_t *abort_with_mutex_no_longjmp(void);
 static void abort_data_structures_from_segment_num(int segment_num);
 
 static inline bool was_read_remote(char *base, object_t *obj,
diff --git a/rpython/translator/stm/src_stm/stm/forksupport.c 
b/rpython/translator/stm/src_stm/stm/forksupport.c
--- a/rpython/translator/stm/src_stm/stm/forksupport.c
+++ b/rpython/translator/stm/src_stm/stm/forksupport.c
@@ -182,20 +182,18 @@
     assert(tl->associated_segment_num == i);
     assert(pr->transaction_state == TS_REGULAR);
     set_gs_register(get_segment_base(i));
+    assert(STM_SEGMENT->segment_num == i);
 
-    rewind_jmp_buf rjbuf;
-    stm_rewind_jmp_enterframe(tl, &rjbuf);
-    if (stm_rewind_jmp_setjmp(tl) == 0) {
+    s_mutex_lock();
 #ifndef NDEBUG
-        pr->running_pthread = pthread_self();
+    pr->running_pthread = pthread_self();
 #endif
-        pr->pub.running_thread->shadowstack = (
-            pr->shadowstack_at_start_of_transaction);
-        strcpy(pr->marker_self, "fork");
-        stm_abort_transaction();
-    }
+    strcpy(pr->marker_self, "fork");
+    tl->shadowstack = NULL;
+    pr->shadowstack_at_start_of_transaction = NULL;
     stm_rewind_jmp_forget(tl);
-    stm_rewind_jmp_leaveframe(tl, &rjbuf);
+    abort_with_mutex_no_longjmp();
+    s_mutex_unlock();
 }
 
 static void forksupport_child(void)
diff --git a/rpython/translator/stm/src_stm/stm/gcpage.c 
b/rpython/translator/stm/src_stm/stm/gcpage.c
--- a/rpython/translator/stm/src_stm/stm/gcpage.c
+++ b/rpython/translator/stm/src_stm/stm/gcpage.c
@@ -364,6 +364,17 @@
     mark_trace(obj, segment_base);
 }
 
+static void *mark_visit_objects_from_ss(void *_, const void *slice, size_t 
size)
+{
+    const struct stm_shadowentry_s *p, *end;
+    p = (const struct stm_shadowentry_s *)slice;
+    end = (const struct stm_shadowentry_s *)(slice + size);
+    for (; p < end; p++)
+        if ((((uintptr_t)p->ss) & 3) == 0)
+            mark_visit_object(p->ss, stm_object_pages);
+    return NULL;
+}
+
 static void mark_visit_from_roots(void)
 {
     if (testing_prebuilt_objs != NULL) {
@@ -393,10 +404,14 @@
 
     long i;
     for (i = 1; i <= NB_SEGMENTS; i++) {
-        if (get_priv_segment(i)->transaction_state != TS_NONE)
+        if (get_priv_segment(i)->transaction_state != TS_NONE) {
             mark_visit_object(
                 get_priv_segment(i)->threadlocal_at_start_of_transaction,
                 get_segment_base(i));
+            stm_rewind_jmp_enum_shadowstack(
+                get_segment(i)->running_thread,
+                mark_visit_objects_from_ss);
+        }
     }
 }
 
diff --git a/rpython/translator/stm/src_stm/stm/marker.c 
b/rpython/translator/stm/src_stm/stm/marker.c
--- a/rpython/translator/stm/src_stm/stm/marker.c
+++ b/rpython/translator/stm/src_stm/stm/marker.c
@@ -19,10 +19,9 @@
     struct stm_shadowentry_s *current = tl->shadowstack - 1;
     struct stm_shadowentry_s *base = tl->shadowstack_base;
 
-    /* The shadowstack_base contains STM_STACK_MARKER_OLD, which is
-       a convenient stopper for the loop below but which shouldn't
-       be returned. */
-    assert(base->ss == (object_t *)STM_STACK_MARKER_OLD);
+    /* The shadowstack_base contains -1, which is a convenient stopper for
+       the loop below but which shouldn't be returned. */
+    assert(base->ss == (object_t *)-1);
 
     while (!(((uintptr_t)current->ss) & 1)) {
         current--;
diff --git a/rpython/translator/stm/src_stm/stm/nursery.c 
b/rpython/translator/stm/src_stm/stm/nursery.c
--- a/rpython/translator/stm/src_stm/stm/nursery.c
+++ b/rpython/translator/stm/src_stm/stm/nursery.c
@@ -157,27 +157,22 @@
 {
     stm_thread_local_t *tl = STM_SEGMENT->running_thread;
     struct stm_shadowentry_s *current = tl->shadowstack;
-    struct stm_shadowentry_s *base = tl->shadowstack_base;
-    while (1) {
+    struct stm_shadowentry_s *finalbase = tl->shadowstack_base;
+    struct stm_shadowentry_s *ssbase;
+    ssbase = (struct stm_shadowentry_s *)tl->rjthread.moved_off_ssbase;
+    if (ssbase == NULL)
+        ssbase = finalbase;
+    else
+        assert(finalbase <= ssbase && ssbase <= current);
+
+    while (current > ssbase) {
         --current;
-        OPT_ASSERT(current >= base);
-
         uintptr_t x = (uintptr_t)current->ss;
 
         if ((x & 3) == 0) {
             /* the stack entry is a regular pointer (possibly NULL) */
             minor_trace_if_young(&current->ss);
         }
-        else if (x == STM_STACK_MARKER_NEW) {
-            /* the marker was not already seen: mark it as seen,
-               but continue looking more deeply in the shadowstack */
-            current->ss = (object_t *)STM_STACK_MARKER_OLD;
-        }
-        else if (x == STM_STACK_MARKER_OLD) {
-            /* the marker was already seen: we can stop the
-               root stack tracing at this point */
-            break;
-        }
         else {
             /* it is an odd-valued marker, ignore */
         }
diff --git a/rpython/translator/stm/src_stm/stm/setup.c 
b/rpython/translator/stm/src_stm/stm/setup.c
--- a/rpython/translator/stm/src_stm/stm/setup.c
+++ b/rpython/translator/stm/src_stm/stm/setup.c
@@ -202,13 +202,13 @@
     struct stm_shadowentry_s *s = (struct stm_shadowentry_s *)start;
     tl->shadowstack = s;
     tl->shadowstack_base = s;
-    STM_PUSH_ROOT(*tl, STM_STACK_MARKER_OLD);
+    STM_PUSH_ROOT(*tl, -1);
 }
 
 static void _done_shadow_stack(stm_thread_local_t *tl)
 {
     assert(tl->shadowstack > tl->shadowstack_base);
-    assert(tl->shadowstack_base->ss == (object_t *)STM_STACK_MARKER_OLD);
+    assert(tl->shadowstack_base->ss == (object_t *)-1);
 
     char *start = (char *)tl->shadowstack_base;
     _shadowstack_trap_page(start, PROT_READ | PROT_WRITE);
diff --git a/rpython/translator/stm/src_stm/stmgc.h 
b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -314,8 +314,6 @@
 #define STM_PUSH_ROOT(tl, p)   ((tl).shadowstack++->ss = (object_t *)(p))
 #define STM_POP_ROOT(tl, p)    ((p) = (typeof(p))((--(tl).shadowstack)->ss))
 #define STM_POP_ROOT_RET(tl)   ((--(tl).shadowstack)->ss)
-#define STM_STACK_MARKER_NEW  (-41)
-#define STM_STACK_MARKER_OLD  (-43)
 
 
 /* Every thread needs to have a corresponding stm_thread_local_t
@@ -346,6 +344,8 @@
     (tl)->shadowstack = (struct stm_shadowentry_s *)     \
         rewind_jmp_restore_shadowstack(&(tl)->rjthread); \
 } while (0)
+#define stm_rewind_jmp_enum_shadowstack(tl, callback)    \
+    rewind_jmp_enum_shadowstack(&(tl)->rjthread, callback)
 
 /* Starting and ending transactions.  stm_read(), stm_write() and
    stm_allocate() should only be called from within a transaction.
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to