Author: Remi Meier <meier...@student.ethz.ch> Branch: implement-id Changeset: r220:c0ff042ed265 Date: 2013-06-21 13:08 +0200 http://bitbucket.org/pypy/stmgc/changeset/c0ff042ed265/
Log: amazingly seems to not crash.. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -446,8 +446,9 @@ B = stmgc_duplicate_old(P); B->h_tid |= GCFLAG_BACKUP_COPY; - if (P->h_tid & GCFLAG_OLD) - B->h_original = P; + if (!(P->h_original) && (P->h_tid & GCFLAG_OLD)) { + B->h_original = (revision_t)P; + } P->h_tid |= GCFLAG_PRIVATE_FROM_PROTECTED; P->h_revision = (revision_t)B; @@ -475,8 +476,10 @@ /* note that stmgc_duplicate() usually returns a young object, but may return an old one if the nursery is full at this moment. */ gcptr L = stmgc_duplicate(R); - if (!(L->h_original)) + if (!(L->h_original)) { + assert(R->h_tid & GCFLAG_OLD); // if not, force stm_id?? L->h_original = (revision_t)R; + } assert(!(L->h_tid & GCFLAG_BACKUP_COPY)); assert(!(L->h_tid & GCFLAG_STUB)); @@ -1010,10 +1013,16 @@ | GCFLAG_OLD; assert(!(L->h_tid & GCFLAG_HAS_ID)); stub->h_revision = ((revision_t)L) | 2; - if (L->h_original) + if (L->h_original) { stub->h_original = L->h_original; - else + } + else if (L->h_tid & GCFLAG_OLD) { + stub->h_original = (revision_t)L; + } + else { L->h_original = (revision_t)stub; + } + item->val = stub; } G2L_LOOP_END; @@ -1091,12 +1100,13 @@ if (bool_cas(&B->h_revision, v, (revision_t)P)) break; } - } - else if (P->h_tid & GCFLAG_HAS_ID) { - /* The backup is the "id object". */ + } + 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; - P->h_tid &= ~GCFLAG_HAS_ID; B->h_revision = (revision_t)P; } else @@ -1139,10 +1149,10 @@ stealing will follow its h_revision (to B). */ } - else if (P->h_tid & GCFLAG_HAS_ID) { + 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; - P->h_tid &= ~GCFLAG_HAS_ID; B->h_tid |= GCFLAG_PUBLIC; B->h_tid &= ~GCFLAG_BACKUP_COPY; if (!(P->h_tid & GCFLAG_OLD)) P->h_tid |= GCFLAG_NURSERY_MOVED; @@ -1152,7 +1162,8 @@ { /* copy the backup copy B back over the now-protected object P, and then free B, which will not be used any more. */ - assert(B->h_original == P); + 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 @@ -101,93 +101,51 @@ struct tx_descriptor *d = thread_descriptor; revision_t result; + spinlock_acquire(d->public_descriptor->collection_lock, 'I'); if (p->h_original) { - fprintf(stderr, "stm_id(%p) has original: %p\n", p, (gcptr)p->h_original); + spinlock_release(d->public_descriptor->collection_lock); return p->h_original; } - spinlock_acquire(d->public_descriptor->collection_lock, 'I'); + /* old objects must have an h_original OR be + the original itself. + if some thread stole p when it was still young, + it must have set h_original. stealing an old obj + makes the old obj "original". + */ if (p->h_tid & GCFLAG_OLD) { /* it must be this exact object */ result = (revision_t)p; } else { - /* must create shadow original object */ - 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; - - fprintf(stderr, "stm_id(%p): is young, preallocate old id-copy %p\n", - p, O); - } - - - if (p->h_original) { - // maybe in the meantime? - fprintf(stderr, "stm_id(%p) has original NOW: %p\n", p, (gcptr)p->h_original); - spinlock_release(d->public_descriptor->collection_lock); - return p->h_original; - } - - //p->h_original == NULL - - if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { - gcptr B = (gcptr)p->h_revision; - if (p->h_tid & GCFLAG_OLD) { - /* may have become old after becoming priv_from_prot */ - if (B->h_tid & GCFLAG_BACKUP_COPY) { - B->h_original = p; - result = (revision_t)p; - fprintf(stderr, "stm_id(%p): is priv_from_prot and old. make "); - } - else { - /* someone stole and assumes the backup as the ID */ - p->h_original = B; - result = (revision_t)B; - } - } - else { - // use backup copy as ID object - p->h_tid |= GCFLAG_HAS_ID; // see AbortPrivateFromProtected + /* must create shadow original object or use + backup, if exists */ + if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { + gcptr B = (gcptr)p->h_revision; + /* don't set, otherwise nursery will copy over backup */ + //p->h_tid |= GCFLAG_HAS_ID; // see AbortPrivateFromProtected p->h_original = (revision_t)B; // B->h_tid |= GCFLAG_PUBLIC; done by CommitPrivateFromProtected result = (revision_t)B; - fprintf(stderr, - "stm_id(%p): is private_from_protected, make the backup %p an id-copy\n", - p, B); } - } - else if (!(p->h_tid & GCFLAG_OLD)) {//(is_in_nursery(p)) { - // preallocate old "original" outside; - // like stealing - gcptr O = stmgc_duplicate_old(p); - //p->h_revision = (revision_t)O; - p->h_original = (revision_t)O; - p->h_tid |= GCFLAG_HAS_ID; - O->h_tid |= GCFLAG_PUBLIC; - - result = (revision_t)O; - - fprintf(stderr, "stm_id(%p): is young, preallocate old id-copy %p\n", - p, O); + else { + 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; + } } - else {// if (p->h_tid & GCFLAG_OLD) { - /* obj is old, possibly private or protected */ - /* last, because there are old private(_from_public) objects */ - result = (revision_t)p; - fprintf(stderr, "stm_id(%p): is itself\n", p); - } - + spinlock_release(d->public_descriptor->collection_lock); return result; } revision_t stm_pointer_equal(gcptr p1, gcptr p2) { + /* XXX: */ return stm_id(p1) == stm_id(p2); } @@ -245,11 +203,6 @@ /* already has a place to go to */ gcptr id_obj = (gcptr)obj->h_original; - /* assert(!(id_obj->h_tid & GCFLAG_BACKUP_COPY)); - well, if it is still a backup, then it wasn't - stolen. We can use it for our young obj. - */ - copy_to_old_id_copy(obj, id_obj); fresh_old_copy = id_obj; obj->h_tid &= ~GCFLAG_HAS_ID; diff --git a/c4/steal.c b/c4/steal.c --- a/c4/steal.c +++ b/c4/steal.c @@ -81,10 +81,16 @@ | GCFLAG_STUB | GCFLAG_OLD; stub->h_revision = ((revision_t)obj) | 2; - if (obj->h_original) + if (obj->h_original) { stub->h_original = obj->h_original; - else + } + else if (obj->h_tid & GCFLAG_OLD) { + stub->h_original = (revision_t)obj; + } + else { obj->h_original = (revision_t)stub; + } + g2l_insert(&sd->all_stubs, obj, stub); if (!(obj->h_tid & GCFLAG_OLD)) @@ -113,19 +119,19 @@ if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { gcptr B = (gcptr)L->h_revision; /* the backup copy */ - if(L->h_tid & GCFLAG_HAS_ID) { - /* if L has ID, then the backup is the "original" */ - assert(L->h_original == (revision_t)B); - L->h_tid &= ~GCFLAG_HAS_ID; // now it's simply stolen - } + if (L->h_original) { + /* may have HAS_ID */ + B->h_original = L->h_original; + } else if (L->h_tid & GCFLAG_OLD) { - /* became old after becoming priv_from_protected - make L the original - */ + assert(!(L->h_tid & GCFLAG_HAS_ID)); + /* original must be L */ B->h_original = (revision_t)L; } - /* otherwise: L is the original */ - assert (!(B->h_tid & GCFLAG_HAS_ID)); + else { + /* we can make the backup the "original" */ + L->h_original = (revision_t)B; + } /* B is now a backup copy, i.e. a protected object, and we own the foreign thread's collection_lock, so we can read/write the @@ -169,8 +175,10 @@ fprintf(stderr, "stolen: %p -> %p\n", P, L); + if (!(L->h_tid & GCFLAG_OLD)) { gcptr O; + if (L->h_tid & GCFLAG_HAS_ID) { /* use id-copy for us */ O = (gcptr)L->h_original; @@ -184,6 +192,7 @@ L->h_revision = (revision_t)O; L->h_original = (revision_t)O; } + L->h_tid |= GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED; /* subtle: we need to remove L from the fxcache of the target thread, otherwise its read barrier might not trigger on it. @@ -195,6 +204,7 @@ L = O; fprintf(stderr, "\t---> %p\n", L); } + assert(L->h_tid & GCFLAG_OLD); } _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit