[pypy-commit] stmgc implement-id: amazingly seems to not crash..
Raemi
noreply at buildbot.pypy.org
Fri Jun 21 13:46:56 CEST 2013
Author: Remi Meier <meierrem at 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);
}
More information about the pypy-commit
mailing list