[pypy-commit] stmgc default: Read the latest version of an object inside the aborting transaction.
arigo
noreply at buildbot.pypy.org
Sat Jul 6 18:52:35 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r361:15dbb73844ab
Date: 2013-07-06 15:38 +0200
http://bitbucket.org/pypy/stmgc/changeset/15dbb73844ab/
Log: Read the latest version of an object inside the aborting
transaction.
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -248,6 +248,36 @@
}
}
+gcptr stm_RepeatReadBarrier(gcptr P)
+{
+ /* Version of stm_DirectReadBarrier() that doesn't abort and assumes
+ * that 'P' was already an up-to-date result of a previous
+ * stm_DirectReadBarrier(). We only have to check if we did in the
+ * meantime a stm_write_barrier().
+ */
+ if (P->h_tid & GCFLAG_PUBLIC)
+ {
+ if (P->h_tid & GCFLAG_NURSERY_MOVED)
+ {
+ P = (gcptr)P->h_revision;
+ assert(P->h_tid & GCFLAG_PUBLIC);
+ }
+ if (P->h_tid & GCFLAG_PUBLIC_TO_PRIVATE)
+ {
+ struct tx_descriptor *d = thread_descriptor;
+ wlog_t *item;
+ G2L_FIND(d->public_to_private, P, item, goto no_private_obj);
+
+ P = item->val;
+ assert(!(P->h_tid & GCFLAG_PUBLIC));
+ no_private_obj:
+ ;
+ }
+ }
+ assert(!(P->h_tid & GCFLAG_STUB));
+ return P;
+}
+
static gcptr _match_public_to_private(gcptr P, gcptr pubobj, gcptr privobj,
int from_stolen)
{
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -181,6 +181,7 @@
void SpinLoop(int);
gcptr stm_DirectReadBarrier(gcptr);
+gcptr stm_RepeatReadBarrier(gcptr);
gcptr stm_WriteBarrier(gcptr);
gcptr _stm_nonrecord_barrier(gcptr); /* debugging: read barrier, but
not recording anything */
diff --git a/c4/extra.c b/c4/extra.c
--- a/c4/extra.c
+++ b/c4/extra.c
@@ -143,6 +143,7 @@
void stm_abort_info_push(gcptr obj, long fieldoffsets[])
{
struct tx_descriptor *d = thread_descriptor;
+ obj = stm_read_barrier(obj);
gcptrlist_insert2(&d->abortinfo, obj, (gcptr)fieldoffsets);
}
@@ -188,7 +189,7 @@
WRITE_BUF(buffer, res_size);
WRITE('e');
for (i=0; i<d->abortinfo.size; i+=2) {
- char *object = (char *)d->abortinfo.items[i+0];
+ char *object = (char *)stm_RepeatReadBarrier(d->abortinfo.items[i+0]);
long *fieldoffsets = (long*)d->abortinfo.items[i+1];
long kind, offset;
size_t rps_size;
diff --git a/c4/test/test_extra.py b/c4/test/test_extra.py
--- a/c4/test/test_extra.py
+++ b/c4/test/test_extra.py
@@ -87,3 +87,19 @@
c = lib.stm_inspect_abort_info()
assert c
assert ffi.string(c).endswith("e0:e")
+
+def test_latest_version():
+ fo1 = ffi.new("long[]", [1, HDR, 0])
+ p = palloc(HDR + WORD)
+ lib.rawsetlong(p, 0, -9827892)
+ #
+ @perform_transaction
+ def run(retry_counter):
+ if retry_counter == 0:
+ lib.stm_abort_info_push(p, fo1)
+ lib.setlong(p, 0, 424242)
+ abort_and_retry()
+ else:
+ c = lib.stm_inspect_abort_info()
+ assert c
+ assert ffi.string(c).endswith("ei424242ee")
More information about the pypy-commit
mailing list