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(¤t->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