[pypy-commit] stmgc default: Aborting, including aborting GCFLAG_PRIVATE_FROM_PROTECTED
arigo
noreply at buildbot.pypy.org
Mon Jun 10 09:49:38 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r90:50f4a1c6ad65
Date: 2013-06-10 09:49 +0200
http://bitbucket.org/pypy/stmgc/changeset/50f4a1c6ad65/
Log: Aborting, including aborting GCFLAG_PRIVATE_FROM_PROTECTED
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -494,6 +494,10 @@
struct timespec now;
long long elapsed_time;
+ /* acquire the lock, but don't double-acquire it if already committing */
+ if (d->public_descriptor->collection_lock != 'C')
+ spinlock_acquire(d->public_descriptor->collection_lock, 'C');
+
assert(d->active != 0);
assert(!is_inevitable(d));
assert(num < ABORT_REASONS);
@@ -566,11 +570,13 @@
d->reads_size_limit_nonatomic = limit;
}
+ AbortPrivateFromProtected(d);
gcptrlist_clear(&d->list_of_read_objects);
- abort();
- gcptrlist_clear(&d->private_from_protected); //XXX clean up
- abort();
- //stmgc_abort_transaction(d);
+ g2l_clear(&d->public_to_private);
+ gcptrlist_clear(&d->public_descriptor->stolen_objects);
+
+ /* release the lock */
+ spinlock_release(d->public_descriptor->collection_lock);
fprintf(stderr,
"\n"
@@ -848,6 +854,35 @@
gcptrlist_clear(&d->private_from_protected);
}
+void AbortPrivateFromProtected(struct tx_descriptor *d)
+{
+ long i, size = d->private_from_protected.size;
+ gcptr *items = d->private_from_protected.items;
+
+ for (i = 0; i < size; i++)
+ {
+ gcptr P = items[i];
+ assert(P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
+ assert(!(P->h_revision & 1)); // "is a pointer"
+
+ gcptr B = (gcptr)P->h_revision;
+ if (B->h_tid & GCFLAG_PUBLIC)
+ {
+ assert(!(B->h_tid & GCFLAG_BACKUP_COPY));
+ P->h_tid &= ~GCFLAG_PRIVATE_FROM_PROTECTED;
+ P->h_tid |= GCFLAG_PUBLIC;
+ /* P becomes a public outdated object */
+ }
+ else
+ {
+ assert(B->h_tid & GCFLAG_BACKUP_COPY);
+ memcpy(P, B, stmcb_size(P));
+ P->h_tid &= ~GCFLAG_BACKUP_COPY;
+ }
+ };
+ gcptrlist_clear(&d->private_from_protected);
+}
+
void CommitTransaction(void)
{ /* must save roots around this call */
revision_t cur_time;
diff --git a/c4/test/test_et.py b/c4/test/test_et.py
--- a/c4/test/test_et.py
+++ b/c4/test/test_et.py
@@ -228,7 +228,7 @@
r.set(3)
run_parallel(f1, f2)
-def test_stealing_while_modifying():
+def test_stealing_while_modifying(aborting=False):
p = palloc(HDR + WORD)
def f1(r):
@@ -239,7 +239,15 @@
pback_ = []
def cb(c):
- assert c == 0
+ if c != 0:
+ assert aborting
+ [pback] = pback_
+ assert classify(p) == "public"
+ assert classify(p1) == "public"
+ assert classify(pback) == "public"
+ assert lib.stm_read_barrier(p) == pback
+ assert lib.stm_read_barrier(p1) == pback
+ return
assert classify(p) == "public"
assert classify(p1) == "protected"
assert classify(follow_revision(p)) == "stub"
@@ -261,16 +269,24 @@
assert lib.stm_read_barrier(p1) == p1
assert lib.stm_read_barrier(pback) == p1
assert pback.h_revision & 1
+ if aborting:
+ abort_and_retry()
perform_transaction(cb)
lib.stm_commit_transaction()
lib.stm_begin_inevitable_transaction()
[pback] = pback_
- assert classify(p1) == "protected"
- assert classify(pback) == "public"
- assert classify(follow_revision(pback)) == "stub"
- assert follow_revision(pback).h_revision == (
- int(ffi.cast("revision_t", p1)) | 2)
+ if aborting:
+ assert classify(p1) == "public"
+ assert classify(pback) == "public"
+ assert pback.h_revision & 1
+ assert p1.h_revision == int(ffi.cast("revision_t", pback))
+ else:
+ assert classify(p1) == "protected"
+ assert classify(pback) == "public"
+ assert classify(follow_revision(pback)) == "stub"
+ assert follow_revision(pback).h_revision == (
+ int(ffi.cast("revision_t", p1)) | 2)
def f2(r):
def cb(c):
@@ -286,3 +302,22 @@
perform_transaction(cb)
run_parallel(f1, f2)
+
+def test_abort_private_from_protected():
+ p = nalloc(HDR + WORD)
+ lib.setlong(p, 0, 897987)
+ lib.stm_commit_transaction()
+ lib.stm_begin_inevitable_transaction()
+ #
+ def cb(c):
+ assert classify(p) == "protected"
+ assert lib.getlong(p, 0) == 897987
+ if c == 0:
+ lib.setlong(p, 0, -38383)
+ assert lib.getlong(p, 0) == -38383
+ assert classify(p) == "private"
+ abort_and_retry()
+ perform_transaction(cb)
+
+def test_abort_stealing_while_modifying():
+ test_stealing_while_modifying(aborting=True)
More information about the pypy-commit
mailing list