Author: Remi Meier <[email protected]>
Branch:
Changeset: r273:d01dac528994
Date: 2013-06-25 14:01 +0200
http://bitbucket.org/pypy/stmgc/changeset/d01dac528994/
Log: do not use backup as shadow-original, always use additional shadow
diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -55,7 +55,6 @@
unsigned int thread_seed;
gcptr roots[MAXROOTS];
gcptr roots_outside_perform[MAXROOTS];
- gcptr current_root;
int num_roots;
int num_roots_outside_perform;
int steps_left;
@@ -68,6 +67,12 @@
int classify(gcptr p);
void check(gcptr p);
+static int is_private(gcptr P)
+{
+ return (P->h_revision == stm_private_rev_num) ||
+ (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
+}
+
int get_rand(int max)
{
return (int)(rand_r(&td.thread_seed) % (unsigned int)max);
@@ -101,7 +106,8 @@
int i;
for (i = 0; i < td.num_roots; i++) {
check(td.roots[i]);
- stm_push_root(td.roots[i]);
+ if (td.roots[i])
+ stm_push_root(td.roots[i]);
}
}
@@ -109,7 +115,8 @@
{
int i;
for (i = td.num_roots - 1; i >= 0; i--) {
- td.roots[i] = stm_pop_root();
+ if (td.roots[i])
+ td.roots[i] = stm_pop_root();
check(td.roots[i]);
}
}
@@ -173,6 +180,7 @@
check(p);
w = stm_write_barrier(p);
check(w);
+ assert(is_private(w));
}
return w;
}
@@ -351,7 +359,7 @@
if (w_t->id) {
assert(w_t->id == stm_id((gcptr)w_t));
assert(w_t->id == stm_id((gcptr)_t));
- }
+ }
else {
w_t = (nodeptr)write_barrier(_t);
w_t->id = stm_id((gcptr)w_t);
@@ -425,9 +433,7 @@
int run_me()
{
gcptr p = NULL;
- while (td.steps_left) {
- td.steps_left--;
-
+ while (td.steps_left-->0) {
if (td.steps_left % 8 == 0)
fprintf(stdout, "#");
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1120,14 +1120,6 @@
break;
}
}
- else if (P->h_original == (revision_t)B) {
- /* The backup is the "id object" */
- assert(!(P->h_tid & GCFLAG_HAS_ID));
-
- B->h_tid &= ~GCFLAG_BACKUP_COPY;
- B->h_tid |= GCFLAG_PUBLIC;
- B->h_revision = (revision_t)P;
- }
else
{
stmgcpage_free(B);
@@ -1159,7 +1151,7 @@
{
assert(!(B->h_tid & GCFLAG_BACKUP_COPY));
P->h_tid |= GCFLAG_PUBLIC;
- P->h_tid &= ~GCFLAG_HAS_ID; // just in case
+ assert(!(P->h_tid & GCFLAG_HAS_ID));
if (!(P->h_tid & GCFLAG_OLD)) P->h_tid |= GCFLAG_NURSERY_MOVED;
/* P becomes a public outdated object. It may create an
exception documented in doc-objects.txt: a public but young
@@ -1168,24 +1160,16 @@
stealing will follow its h_revision (to B).
*/
}
- else if (P->h_original == (revision_t)B) {
- /* The backup is the "id object". P becomes outdated. */
- assert(!(P->h_tid & GCFLAG_HAS_ID));
- P->h_tid |= GCFLAG_PUBLIC;
- B->h_tid |= GCFLAG_PUBLIC;
- B->h_tid &= ~GCFLAG_BACKUP_COPY;
- if (!(P->h_tid & GCFLAG_OLD)) P->h_tid |= GCFLAG_NURSERY_MOVED;
- }
else
{
/* copy the backup copy B back over the now-protected object P,
and then free B, which will not be used any more. */
-
+ assert(!(P->h_original)
+ || (B->h_original == (revision_t)P->h_original));
+ assert(!(P->h_original && !B->h_original));
if (P->h_original && !B->h_original) // might occur because of
B->h_original = P->h_original; //replace_ptr_to_protected_with_stub
- assert(!(P->h_original)
- || (B->h_original == (revision_t)P->h_original));
size_t size = stmcb_size(B);
assert(B->h_tid & GCFLAG_BACKUP_COPY);
memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision),
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -159,18 +159,10 @@
p, (gcptr)p->h_original));
return p->h_original;
}
- else if (!(p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
- && (p->h_tid & GCFLAG_OLD)) {
- /* we can be sure that p->h_original doesn't
- get set during the if and the else-if
-
- XXX: check for priv_from_protected may not be
- necessary. only if this func may be called on
- another thread's young objects that are made
- old at the same time, and we see the OLD flag
- before h_original has been set.
- */
- dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p));
+ else if (p->h_tid & GCFLAG_OLD) {
+ /* old objects must have an h_original xOR be
+ the original itself. */
+ /* dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p)); */
return (revision_t)p;
}
@@ -188,35 +180,24 @@
dprintf(("stm_id(%p) has orig: %p\n",
p, (gcptr)p->h_original));
}
- else if (p->h_tid & GCFLAG_OLD) {
- /* it must be this exact object */
- result = (revision_t)p;
- dprintf(("stm_id(%p) is old, orig=0: %p\n", p, p));
- }
else {
- /* must create shadow original object or use
+ /* must create shadow original object XXX: or use
backup, if exists */
+
+ /* XXX use stmgcpage_malloc() directly, we don't need to copy
+ * the contents yet */
+ gcptr O = stmgc_duplicate_old(p);
+ p->h_original = (revision_t)O;
+ p->h_tid |= GCFLAG_HAS_ID;
+ O->h_tid |= GCFLAG_PUBLIC;
+
if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
gcptr B = (gcptr)p->h_revision;
- /* don't set HAS_ID, otherwise nursery will copy over backup */
- p->h_original = (revision_t)B;
- // B->h_tid |= GCFLAG_PUBLIC; done by CommitPrivateFromProtected
-
- result = (revision_t)B;
- dprintf(("stm_id(%p) young, pfp, use backup %p\n",
- p, (gcptr)p->h_original));
+ B->h_original = (revision_t)O;
}
- else {
- /* XXX use stmgcpage_malloc() directly, we don't need to copy
- * the contents yet */
- gcptr O = stmgc_duplicate_old(p);
- p->h_original = (revision_t)O;
- p->h_tid |= GCFLAG_HAS_ID;
- O->h_tid |= GCFLAG_PUBLIC;
-
- result = (revision_t)O;
- dprintf(("stm_id(%p) young, make shadow %p\n", p, O));
- }
+
+ result = (revision_t)O;
+ dprintf(("stm_id(%p) young, make shadow %p\n", p, O));
}
spinlock_release(d->public_descriptor->collection_lock);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -96,6 +96,7 @@
if (L->h_original) {
/* L has an original, may be GCFLAG_HAS_ID */
B->h_original = L->h_original;
+ L->h_tid &= ~GCFLAG_HAS_ID;
}
else if (L->h_tid & GCFLAG_OLD) {
/* If old, it must be the original */
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
@@ -498,10 +498,11 @@
test_stub_for_refs_from_stolen(old=True)
-def id_with_stealing(a=0, b=0):
+def id_with_stealing(a, b, c):
p = palloc_refs(2)
qlist = []
rlist = []
+ plist = []
qid = []
pid = []
rid = []
@@ -509,13 +510,14 @@
r1 = nalloc(HDR)
q1 = nalloc(HDR)
p1 = lib.stm_write_barrier(p) # private copy
+ plist.append(p1)
qlist.append(q1)
rlist.append(r1)
- if a:
+ if c and a:
# id on young priv
qid.append(lib.stm_id(q1))
assert q1.h_tid & GCFLAG_HAS_ID
- if b:
+ if c and b:
# id on pub_to_priv
assert follow_original(p1) == p
pid.append(lib.stm_id(p1))
@@ -526,21 +528,23 @@
lib.stm_begin_inevitable_transaction()
# p old public -> stub -> p1 young prot
# q1 young prot, r1 young prot
- if not a:
+ if c and not a:
# id on young prot
qid.append(lib.stm_id(q1))
assert q1.h_tid & GCFLAG_HAS_ID
- if not b:
+ if c and not b:
# id on young prot
assert follow_original(p1) == p
pid.append(lib.stm_id(p1))
assert not (p1.h_tid & GCFLAG_HAS_ID)
- r1w = lib.stm_write_barrier(r1) # priv_from_prot
- assert r1w.h_tid & GCFLAG_PRIVATE_FROM_PROTECTED
- rid.append(lib.stm_id(r1w))
- assert not (r1w.h_tid & GCFLAG_HAS_ID) # use backup
- assert follow_original(r1w) == follow_revision(r1w)
+ r1w = lib.stm_write_barrier(r1)
+ assert classify(r1w) == "private_from_protected"
+ assert not (r1w.h_tid & GCFLAG_OLD)
+ if c:
+ rid.append(lib.stm_id(r1w))
+ # assert not (r1w.h_tid & GCFLAG_HAS_ID) # use backup <- XXX
+ # assert follow_original(r1w) == follow_revision(r1w)
r.set(2)
r.wait(3) # wait until the other thread really started
@@ -548,26 +552,45 @@
r.wait(2)
r.set(3)
- p2 = lib.stm_read_barrier(p) # steals
+ assert classify(plist[-1]) == "protected"
+ p2 = lib.stm_read_barrier(plist[-1]) # steals
+ if not c:
+ pid.append(lib.stm_id(p2))
assert pid[-1] == lib.stm_id(p2)
r2 = lib.getptr(p2, 1)
r3 = lib.stm_read_barrier(r2)
+ if not c:
+ rid.append(lib.stm_id(r3))
assert lib.stm_id(r3) == rid[-1]
q2 = lib.getptr(p2, 0)
+ q3 = lib.stm_read_barrier(q2)
+ if not c:
+ qid.append(lib.stm_id(q3))
+
+ assert lib.stm_id(q3) == qid[-1]
assert lib.stm_id(q2) == qid[-1]
- q3 = lib.stm_read_barrier(q2)
- assert lib.stm_id(q3) == qid[-1]
-
run_parallel(f1, f2)
def test_id_with_stealing():
- id_with_stealing(1, 1)
- id_with_stealing(1, 0)
- id_with_stealing(0, 1)
- id_with_stealing(0, 0)
+ id_with_stealing(1, 1, 0)
+def test_id_with_stealing1():
+ id_with_stealing(1, 0, 0)
+def test_id_with_stealing2():
+ id_with_stealing(0, 1, 0)
+def test_id_with_stealing3():
+ id_with_stealing(0, 0, 0)
+def test_id_with_stealing4():
+ id_with_stealing(1, 1, 1)
+def test_id_with_stealing5():
+ id_with_stealing(1, 0, 1)
+def test_id_with_stealing6():
+ id_with_stealing(0, 1, 1)
+def test_id_with_stealing7():
+ id_with_stealing(0, 0, 1)
+
def test_prehash_simple():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit