[pypy-commit] pypy stm-thread-2: Extend the last_abort_info with bits and pieces from the tx_descriptor
arigo
noreply at buildbot.pypy.org
Fri Feb 22 17:48:59 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread-2
Changeset: r61618:e8d90c408313
Date: 2013-02-22 16:33 +0100
http://bitbucket.org/pypy/pypy/changeset/e8d90c408313/
Log: Extend the last_abort_info with bits and pieces from the
tx_descriptor as well as a timing of the real time lost in the
aborted transaction.
diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -10,6 +10,7 @@
#include <string.h>
#include <assert.h>
#include <pthread.h>
+#include <time.h>
#ifndef RPY_STM
/* for tests, a few custom defines */
@@ -48,6 +49,7 @@
unsigned long reads_size_limit_nonatomic;
int active; /* 0 = inactive, 1 = regular, 2 = inevitable */
int readonly_updates;
+ struct timespec start_real_time;
unsigned int num_commits;
unsigned int num_aborts[ABORT_REASONS];
unsigned int num_spinloops[SPINLOOP_REASONS];
@@ -370,13 +372,16 @@
spinloop();
}
-size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output);
+size_t _stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time,
+ int abort_reason, char *output);
static void AbortTransaction(int num)
{
struct tx_descriptor *d = thread_descriptor;
unsigned long limit;
size_t size;
+ struct timespec now;
+ long long elapsed_time;
assert(d->active);
assert(!is_inevitable(d));
assert(num < ABORT_REASONS);
@@ -384,13 +389,28 @@
CancelLocks(d);
+ /* compute the elapsed time */
+ if (d->start_real_time.tv_nsec != -1 &&
+ clock_gettime(CLOCK_MONOTONIC, &now) >= 0) {
+ elapsed_time = now.tv_sec - d->start_real_time.tv_sec;
+ elapsed_time *= 1000000000;
+ elapsed_time += now.tv_nsec - d->start_real_time.tv_nsec;
+ }
+ else {
+ elapsed_time = -1;
+ }
+
/* decode the 'abortinfo' and produce a human-readable summary in
the string 'lastabortinfo' */
- size = _stm_decode_abort_info(d, NULL);
+ size = _stm_decode_abort_info(d, elapsed_time, num, NULL);
free(d->lastabortinfo);
d->lastabortinfo = malloc(size);
if (d->lastabortinfo != NULL)
- _stm_decode_abort_info(d, d->lastabortinfo);
+ if (_stm_decode_abort_info(d, elapsed_time, num, d->lastabortinfo) != size)
+ {
+ fprintf(stderr, "during stm abort: object mutated unexpectedly\n");
+ abort();
+ }
/* run the undo log in reverse order, cancelling the values set by
stm_ThreadLocalRef_LLSet(). */
@@ -447,6 +467,9 @@
static void init_transaction(struct tx_descriptor *d)
{
+ if (clock_gettime(CLOCK_MONOTONIC, &d->start_real_time) < 0) {
+ d->start_real_time.tv_nsec = -1;
+ }
assert(d->active == 0);
assert(d->list_of_read_objects.size == 0);
assert(d->gcroots.size == 0);
diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c
--- a/rpython/translator/stm/src_stm/rpyintf.c
+++ b/rpython/translator/stm/src_stm/rpyintf.c
@@ -214,13 +214,16 @@
gcptrlist_reduce_size(&d->abortinfo, newsize < 0 ? 0 : newsize);
}
-size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output)
+size_t _stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time,
+ int abort_reason, char *output)
{
/* re-encodes the abort info as a single string.
For convenience (no escaping needed, no limit on integer
sizes, etc.) we follow the bittorrent format. */
size_t totalsize = 0;
long i;
+ char buffer[32];
+ size_t res_size;
#define WRITE(c) { totalsize++; if (output) *output++=(c); }
#define WRITE_BUF(p, sz) { totalsize += (sz); \
if (output) { \
@@ -228,12 +231,28 @@
} \
}
WRITE('l');
+ WRITE('l');
+ res_size = sprintf(buffer, "i%llde", (long long)elapsed_time);
+ WRITE_BUF(buffer, res_size);
+ res_size = sprintf(buffer, "i%de", (int)abort_reason);
+ WRITE_BUF(buffer, res_size);
+ res_size = sprintf(buffer, "i%lde", (long)(d->my_lock - LOCKED));
+ WRITE_BUF(buffer, res_size);
+ res_size = sprintf(buffer, "i%lde", (long)d->atomic);
+ WRITE_BUF(buffer, res_size);
+ res_size = sprintf(buffer, "i%de", (int)d->active);
+ WRITE_BUF(buffer, res_size);
+ res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads);
+ WRITE_BUF(buffer, res_size);
+ res_size = sprintf(buffer, "i%lue",
+ (unsigned long)d->reads_size_limit_nonatomic);
+ WRITE_BUF(buffer, res_size);
+ WRITE('e');
for (i=0; i<d->abortinfo.size; i+=2) {
char *object = (char *)stm_RepeatReadBarrier(d->abortinfo.items[i+0]);
long *fieldoffsets = (long*)d->abortinfo.items[i+1];
long kind, offset;
- char buffer[32];
- size_t res_size, rps_size;
+ size_t rps_size;
RPyString *rps;
while (1) {
diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -143,7 +143,7 @@
globf.xy = 100 + retry_counter
def check(_, retry_counter):
- rstm.abort_info_push(globf, ('xy', '[', 'yx', ']'))
+ rstm.abort_info_push(globf, ('[', 'xy', ']', 'yx'))
setxy(globf, retry_counter)
if retry_counter < 3:
rstm.abort_and_retry()
@@ -163,4 +163,4 @@
return 0
t, cbuilder = self.compile(main)
data = cbuilder.cmdexec('a b')
- assert 'li102el10:hi there 3ee\n' in data
+ assert 'li102ee10:hi there 3e\n' in data
More information about the pypy-commit
mailing list