[pypy-commit] pypy stmgc-c7: import stmgc/035e1c7879be (from branch "marker")
arigo
noreply at buildbot.pypy.org
Sat Apr 19 14:05:59 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r70767:89b063cce2ab
Date: 2014-04-19 12:39 +0200
http://bitbucket.org/pypy/pypy/changeset/89b063cce2ab/
Log: import stmgc/035e1c7879be (from branch "marker")
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 @@
-918b1901b1f9
+035e1c7879be
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
@@ -621,6 +621,9 @@
(int)pseg->transaction_state);
}
+ /* look up and preserve the marker information as a string */
+ marker_fetch_expand(pseg);
+
/* throw away the content of the nursery */
long bytes_in_nursery = throw_away_nursery(pseg);
@@ -631,6 +634,7 @@
value before the transaction start */
stm_thread_local_t *tl = pseg->pub.running_thread;
assert(tl->shadowstack >= pseg->shadowstack_at_start_of_transaction);
+ pseg->shadowstack_at_abort = tl->shadowstack;
tl->shadowstack = pseg->shadowstack_at_start_of_transaction;
tl->thread_local_obj = pseg->threadlocal_at_start_of_transaction;
tl->last_abort__bytes_in_nursery = bytes_in_nursery;
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
@@ -153,11 +153,15 @@
'thread_local_obj' field. */
struct stm_shadowentry_s *shadowstack_at_start_of_transaction;
object_t *threadlocal_at_start_of_transaction;
+ struct stm_shadowentry_s *shadowstack_at_abort;
/* For debugging */
#ifndef NDEBUG
pthread_t running_pthread;
#endif
+
+ /* Temporarily stores the marker information */
+ char marker_self[_STM_MARKER_LEN];
};
enum /* safe_point */ {
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
@@ -380,7 +380,7 @@
struct stm_shadowentry_s *current = tl->shadowstack;
struct stm_shadowentry_s *base = tl->shadowstack_base;
while (current-- != base) {
- if (((uintptr_t)current->ss) > STM_STACK_MARKER_OLD)
+ if ((((uintptr_t)current->ss) & 3) == 0)
mark_visit_object(current->ss, segment_base);
}
mark_visit_object(tl->thread_local_obj, segment_base);
diff --git a/rpython/translator/stm/src_stm/stm/marker.c b/rpython/translator/stm/src_stm/stm/marker.c
new file mode 100644
--- /dev/null
+++ b/rpython/translator/stm/src_stm/stm/marker.c
@@ -0,0 +1,65 @@
+/* Imported by rpython/translator/stm/import_stmgc.py */
+#ifndef _STM_CORE_H_
+# error "must be compiled via stmgc.c"
+#endif
+
+
+void (*stmcb_expand_marker)(uintptr_t odd_number,
+ object_t *following_object,
+ char *outputbuf, size_t outputbufsize);
+
+
+static void marker_fetch_expand(struct stm_priv_segment_info_s *pseg)
+{
+ if (pseg->marker_self[0] != 0)
+ return; /* already collected an entry */
+
+ if (stmcb_expand_marker != NULL) {
+ stm_thread_local_t *tl = pseg->pub.running_thread;
+ struct stm_shadowentry_s *current = tl->shadowstack - 1;
+ struct stm_shadowentry_s *base = tl->shadowstack_base;
+ while (--current >= base) {
+ uintptr_t x = (uintptr_t)current->ss;
+ if (x & 1) {
+ /* the stack entry is an odd number */
+ stmcb_expand_marker(x, current[1].ss,
+ pseg->marker_self, _STM_MARKER_LEN);
+
+ if (pseg->marker_self[0] == 0) {
+ pseg->marker_self[0] = '?';
+ pseg->marker_self[1] = 0;
+ }
+ break;
+ }
+ }
+ }
+}
+
+char *_stm_expand_marker(void)
+{
+ struct stm_priv_segment_info_s *pseg =
+ get_priv_segment(STM_SEGMENT->segment_num);
+ pseg->marker_self[0] = 0;
+ marker_fetch_expand(pseg);
+ return pseg->marker_self;
+}
+
+static void marker_copy(stm_thread_local_t *tl,
+ struct stm_priv_segment_info_s *pseg,
+ enum stm_time_e attribute_to, double time)
+{
+ /* Copies the marker information from pseg to tl. This is called
+ indirectly from abort_with_mutex(), but only if the lost time is
+ greater than that of the previous recorded marker. By contrast,
+ pseg->marker_self has been filled already in all cases. The
+ reason for the two steps is that we must fill pseg->marker_self
+ earlier than now (some objects may be GCed), but we only know
+ here the total time it gets attributed.
+ */
+ if (time * 0.99 > tl->longest_marker_time) {
+ tl->longest_marker_state = attribute_to;
+ tl->longest_marker_time = time;
+ memcpy(tl->longest_marker_self, pseg->marker_self, _STM_MARKER_LEN);
+ }
+ pseg->marker_self[0] = 0;
+}
diff --git a/rpython/translator/stm/src_stm/stm/marker.h b/rpython/translator/stm/src_stm/stm/marker.h
new file mode 100644
--- /dev/null
+++ b/rpython/translator/stm/src_stm/stm/marker.h
@@ -0,0 +1,6 @@
+/* Imported by rpython/translator/stm/import_stmgc.py */
+
+static void marker_fetch_expand(struct stm_priv_segment_info_s *pseg);
+static void marker_copy(stm_thread_local_t *tl,
+ struct stm_priv_segment_info_s *pseg,
+ enum stm_time_e attribute_to, double time);
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
@@ -161,28 +161,26 @@
--current;
OPT_ASSERT(current >= base);
- switch ((uintptr_t)current->ss) {
+ uintptr_t x = (uintptr_t)current->ss;
- case 0: /* NULL */
- continue;
-
- case STM_STACK_MARKER_NEW:
+ 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;
- continue;
-
- case 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 */
- goto interrupt;
-
- default:
- /* the stack entry is a regular pointer */
- minor_trace_if_young(¤t->ss);
+ break;
+ }
+ else {
+ /* it is an odd-valued marker, ignore */
}
}
- interrupt:
minor_trace_if_young(&tl->thread_local_obj);
}
diff --git a/rpython/translator/stm/src_stm/stm/timing.c b/rpython/translator/stm/src_stm/stm/timing.c
--- a/rpython/translator/stm/src_stm/stm/timing.c
+++ b/rpython/translator/stm/src_stm/stm/timing.c
@@ -36,8 +36,15 @@
{
stm_thread_local_t *tl = STM_SEGMENT->running_thread;
TIMING_CHANGE(tl, STM_TIME_OUTSIDE_TRANSACTION);
- add_timing(tl, attribute_to, tl->timing[STM_TIME_RUN_CURRENT]);
+ double time_this_transaction = tl->timing[STM_TIME_RUN_CURRENT];
+ add_timing(tl, attribute_to, time_this_transaction);
tl->timing[STM_TIME_RUN_CURRENT] = 0.0f;
+
+ if (attribute_to != STM_TIME_RUN_COMMITTED) {
+ struct stm_priv_segment_info_s *pseg =
+ get_priv_segment(STM_SEGMENT->segment_num);
+ marker_copy(tl, pseg, attribute_to, time_this_transaction);
+ }
}
static const char *timer_names[] = {
@@ -74,6 +81,10 @@
fprintf(stderr, " %-24s %9u %8.3f s\n",
timer_names[i], tl->events[i], (double)tl->timing[i]);
}
+ fprintf(stderr, " %-24s %6s %11.6f s\n",
+ "longest recorded marker", "", tl->longest_marker_time);
+ fprintf(stderr, " \"%.*s\"\n",
+ (int)_STM_MARKER_LEN, tl->longest_marker_self);
s_mutex_unlock();
}
}
diff --git a/rpython/translator/stm/src_stm/stmgc.c b/rpython/translator/stm/src_stm/stmgc.c
--- a/rpython/translator/stm/src_stm/stmgc.c
+++ b/rpython/translator/stm/src_stm/stmgc.c
@@ -15,6 +15,7 @@
#include "stm/fprintcolor.h"
#include "stm/weakref.h"
#include "stm/timing.h"
+#include "stm/marker.h"
#include "stm/misc.c"
#include "stm/list.c"
@@ -34,3 +35,4 @@
#include "stm/fprintcolor.c"
#include "stm/weakref.c"
#include "stm/timing.c"
+#include "stm/marker.c"
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
@@ -74,6 +74,8 @@
_STM_TIME_N
};
+#define _STM_MARKER_LEN 80
+
typedef struct stm_thread_local_s {
/* every thread should handle the shadow stack itself */
struct stm_shadowentry_s *shadowstack, *shadowstack_base;
@@ -91,6 +93,11 @@
float timing[_STM_TIME_N];
double _timing_cur_start;
enum stm_time_e _timing_cur_state;
+ /* the marker with the longest associated time so far */
+ enum stm_time_e longest_marker_state;
+ double longest_marker_time;
+ char longest_marker_self[_STM_MARKER_LEN];
+ char longest_marker_other[_STM_MARKER_LEN];
/* the next fields are handled internally by the library */
int associated_segment_num;
struct stm_thread_local_s *prev, *next;
@@ -265,8 +272,8 @@
#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 1
-#define STM_STACK_MARKER_OLD 2
+#define STM_STACK_MARKER_NEW 2
+#define STM_STACK_MARKER_OLD 6
/* Every thread needs to have a corresponding stm_thread_local_t
@@ -369,6 +376,41 @@
void stm_flush_timing(stm_thread_local_t *tl, int verbose);
+/* The markers pushed in the shadowstack are an odd number followed by a
+ regular pointer. When needed, this library invokes this callback to
+ turn this pair into a human-readable explanation. */
+extern void (*stmcb_expand_marker)(uintptr_t odd_number,
+ object_t *following_object,
+ char *outputbuf, size_t outputbufsize);
+
+/* Conventience macros to push the markers into the shadowstack */
+#define STM_PUSH_MARKER(tl, odd_num, p) do { \
+ uintptr_t _odd_num = (odd_num); \
+ assert(_odd_num & 1); \
+ STM_PUSH_ROOT(tl, _odd_num); \
+ STM_PUSH_ROOT(tl, p); \
+} while (0)
+
+#define STM_POP_MARKER(tl) ({ \
+ object_t *_popped = STM_POP_ROOT_RET(tl); \
+ STM_POP_ROOT_RET(tl); \
+ _popped; \
+})
+
+#define STM_UPDATE_MARKER_NUM(tl, odd_num) do { \
+ uintptr_t _odd_num = (odd_num); \
+ assert(_odd_num & 1); \
+ struct stm_shadowentry_s *_ss = (tl).shadowstack - 2; \
+ while (!(((uintptr_t)(_ss->ss)) & 1)) { \
+ _ss--; \
+ assert(_ss >= (tl).shadowstack_base); \
+ } \
+ _ss->ss = (object_t *)_odd_num; \
+} while (0)
+
+char *_stm_expand_marker(void);
+
+
/* ==================== END ==================== */
#endif
More information about the pypy-commit
mailing list