Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r139:cb8059368058 Date: 2013-06-15 22:46 +0200 http://bitbucket.org/pypy/stmgc/changeset/cb8059368058/
Log: Fix: dont call stmgc_duplicate() when we hold the collection_lock. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -414,7 +414,7 @@ return P; /* always returns its arg: the object is converted in-place */ } -static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R) +static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R, gcptr L) { assert(R->h_tid & GCFLAG_PUBLIC); @@ -427,7 +427,6 @@ R->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE; - gcptr L = stmgc_duplicate(R); assert(!(L->h_tid & GCFLAG_BACKUP_COPY)); assert(!(L->h_tid & GCFLAG_STUB)); assert(!(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)); @@ -472,7 +471,7 @@ return P; } - gcptr R, W; + gcptr R, L, W; R = stm_read_barrier(P); if (is_private(R)) @@ -484,6 +483,13 @@ struct tx_descriptor *d = thread_descriptor; assert(d->active >= 1); + L = NULL; + if (R->h_tid & GCFLAG_PUBLIC) + { + retry: + L = stmgc_duplicate(R); + } + /* We need the collection_lock for the sequel; this is required notably because we're about to edit flags on a protected object. */ @@ -493,12 +499,19 @@ if (R->h_tid & GCFLAG_PUBLIC) { + if (L == NULL) + { + /* Oups, the flags on R changed while we where waiting for + the collection_lock. */ + spinlock_release(d->public_descriptor->collection_lock); + goto retry; + } /* Make and return a new (young) private copy of the public R. Add R into the list 'public_with_young_copy'. */ assert(R->h_tid & GCFLAG_OLD); gcptrlist_insert(&d->public_with_young_copy, R); - W = LocalizePublic(d, R); + W = LocalizePublic(d, R, L); assert(is_private(W)); } else _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit