Author: Remi Meier <meier...@student.ethz.ch> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit