[pypy-commit] stmgc default: Change again: don't pretend to have the identity of the stolen-from
arigo
noreply at buildbot.pypy.org
Sun May 26 16:54:44 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r18:ab86b5cb7472
Date: 2013-05-26 16:12 +0200
http://bitbucket.org/pypy/stmgc/changeset/ab86b5cb7472/
Log: Change again: don't pretend to have the identity of the stolen-from
thread. This doesn't work correctly with the calls to
stmgcpage_malloc().
diff --git a/c3/et.c b/c3/et.c
--- a/c3/et.c
+++ b/c3/et.c
@@ -301,6 +301,7 @@
not_found:;
gcptr L = stmgc_duplicate(R, 0);
+ assert(L->h_revision == stm_local_revision);
g2l_insert(&d->public_to_private, R, L);
gcptrlist_insert(&d->public_to_young, R);
AddInReadSet(d, R);
@@ -746,11 +747,9 @@
gcptrlist_clear(&d->list_of_read_objects);
fprintf(stderr, "\n"
- "***************************************************************\n"
- "***************************************************************\n"
- "************************************* %ld\n"
- "***************************************************************\n"
- "***************************************************************\n",
+ "*************************************\n"
+ "************************************** committed %ld\n"
+ "*************************************\n",
(long)cur_time);
revision_t localrev = stm_local_revision;
diff --git a/c3/gcpage.c b/c3/gcpage.c
--- a/c3/gcpage.c
+++ b/c3/gcpage.c
@@ -557,9 +557,9 @@
*/
thread_descriptor = d;
stm_local_revision = *d->local_revision_ref;
- assert(stmgc_nursery_hiding(0));
+ assert(stmgc_nursery_hiding(d, 0));
stmgc_minor_collect_no_abort();
- assert(stmgc_nursery_hiding(1));
+ assert(stmgc_nursery_hiding(d, 1));
}
}
thread_descriptor = saved;
diff --git a/c3/nursery.c b/c3/nursery.c
--- a/c3/nursery.c
+++ b/c3/nursery.c
@@ -179,6 +179,8 @@
void stmgc_start_transaction(struct tx_descriptor *d)
{
+ assert(!d->collection_lock); /* with no protected objects so far, no
+ other thread can be stealing */
assert(!gcptrlist_size(&d->protected_with_private_copy));
assert(!g2l_any_entry(&d->public_to_private));
assert(!gcptrlist_size(&d->private_old_pointing_to_young));
@@ -457,6 +459,7 @@
/* then we record the dependency in the dictionary
'public_to_private' */
+ assert(L->h_revision == stm_local_revision);
g2l_insert(&d->public_to_private, R, L);
/*mark*/
}
@@ -657,11 +660,7 @@
static void create_yo_stubs(gcptr *pobj)
{
gcptr obj = *pobj;
- if (obj == NULL)
- return;
-
- struct tx_descriptor *d = thread_descriptor;
- if (!stmgc_is_young_in(d, obj))
+ if (obj == NULL || (obj->h_tid & GCFLAG_OLD) != 0)
return;
/* xxx try to avoid duplicate stubs for the same object */
@@ -800,10 +799,9 @@
gcptrlist_insert(&d->private_old_pointing_to_young, obj);
}
-int stmgc_nursery_hiding(int hide)
+int stmgc_nursery_hiding(struct tx_descriptor *d, int hide)
{
#ifdef _GC_DEBUG
- struct tx_descriptor *d = thread_descriptor;
wlog_t *item;
revision_t count;
@@ -855,16 +853,16 @@
/************************************************************/
-static gcptr extract_from_foreign_nursery(gcptr R)
+static gcptr extract_from_foreign_nursery(struct tx_descriptor *source_d,
+ gcptr R)
{
/* "Stealing": this function follows a chain of protected objects in
- the foreign nursery of the thread temporarily in
- 'thread_descriptor'. It copies the last one outside the nursery,
- and return it. */
+ the foreign nursery of the thread 'source_d'. It copies the last
+ one outside the nursery, and return it. */
gcptr R2, N;
revision_t source_local_rev, v;
- source_local_rev = stm_local_revision;
+ source_local_rev = *source_d->local_revision_ref;
v = ACCESS_ONCE(R->h_revision);
/* check that R is a protected object */
@@ -895,9 +893,9 @@
}
/* R is now the protected object to move outside, with revision v. */
- N = create_old_object_copy(R _REASON("stolen copy"));
+ N = create_old_object_copy(R _REASON("**stolen copy"));
N->h_revision = v;
- gcptrlist_insert2(&thread_descriptor->stolen_objects, R, N);
+ gcptrlist_insert2(&source_d->stolen_objects, R, N);
/* there might be references in N going to protected objects. We
must fix them with stubs. */
@@ -915,7 +913,6 @@
for the other thread to do a minor collection, because it might
be blocked in a system call or whatever. */
struct tx_descriptor *my_d = thread_descriptor;
- revision_t my_local_rev = stm_local_revision;
/* repeat the checks in the caller, to avoid passing more than one
argument here */
@@ -940,33 +937,30 @@
retry.
*/
if (P->h_revision == v) {
- /* temporarily take the identity of source_d */
- thread_descriptor = source_d;
- stm_local_revision = *source_d->local_revision_ref;
-
+ /* careful here: all 'thread_descriptor' accesses will continue
+ to get the current thread (needed e.g. for stmgcpage_malloc())
+ which is different from 'source_d', the source thread out of
+ which we are stealing. */
fprintf(stderr, "STEALING: %p->h_revision points to %p\n", P, R);
/* debugging support: "activate" the foreign nursery */
- assert(stmgc_nursery_hiding(0));
+ assert(stmgc_nursery_hiding(source_d, 0));
/* copy the protected source object */
- gcptr N = extract_from_foreign_nursery(R);
+ gcptr N = extract_from_foreign_nursery(source_d, R);
/* make sure the copy N is visible to other threads before we
change P->h_revision */
smp_wmb();
/* do the change to P->h_revision */
+ assert(bool_cas(&P->h_revision, ((revision_t)R) | 2, (revision_t)N));
ACCESS_ONCE(P->h_revision) = (revision_t)N;
fprintf(stderr, "STEALING: %p->h_revision changed from %p to %p\n",
P, R, N);
/* debugging support: "deactivate" the foreign nursery again */
- assert(stmgc_nursery_hiding(1));
-
- /* restore my own identity */
- stm_local_revision = my_local_rev;
- thread_descriptor = my_d;
+ assert(stmgc_nursery_hiding(source_d, 1));
}
spinlock_release(source_d->collection_lock);
}
@@ -980,6 +974,7 @@
*/
long i, size = d->stolen_objects.size;
gcptr *items = d->stolen_objects.items;
+ assert(d == thread_descriptor);
for (i = 0; i < size; i += 2) {
gcptr R = items[i];
@@ -1003,6 +998,7 @@
/* we re-insert L as a private copy of the public object N */
N->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE;
+ assert(L->h_revision == stm_local_revision);
g2l_insert(&d->public_to_private, N, L);
gcptrlist_insert(&d->public_to_young, N);
}
diff --git a/c3/nursery.h b/c3/nursery.h
--- a/c3/nursery.h
+++ b/c3/nursery.h
@@ -46,7 +46,7 @@
enum protection_class_t stmgc_classify(gcptr);
int stmgc_is_young_in(struct tx_descriptor *, gcptr);
void stmgc_public_to_foreign_protected(gcptr);
-int stmgc_nursery_hiding(int);
+int stmgc_nursery_hiding(struct tx_descriptor *, int);
void stmgc_normalize_stolen_objects(void);
#ifdef _GC_DEBUG
diff --git a/c3/stmsync.c b/c3/stmsync.c
--- a/c3/stmsync.c
+++ b/c3/stmsync.c
@@ -236,12 +236,12 @@
{
int err = pthread_rwlock_rdlock(&rwlock_shared);
assert(err == 0);
- assert(stmgc_nursery_hiding(0));
+ assert(stmgc_nursery_hiding(thread_descriptor, 0));
}
void stm_stop_sharedlock(void)
{
- assert(stmgc_nursery_hiding(1));
+ assert(stmgc_nursery_hiding(thread_descriptor, 1));
int err = pthread_rwlock_unlock(&rwlock_shared);
assert(err == 0);
}
diff --git a/c3/test/test_nursery.py b/c3/test/test_nursery.py
--- a/c3/test/test_nursery.py
+++ b/c3/test/test_nursery.py
@@ -272,9 +272,13 @@
def cb(c):
assert c == 0
p4 = lib.stm_write_barrier(p1)
+ assert lib.in_nursery(p4)
+ assert p4 != p1 and p4 != pg
assert lib.rawgetlong(p4, 0) == 9387987
+ print "changing p4=%r to contain -6666" % (p4,)
lib.rawsetlong(p4, 0, -6666)
r.wait_while_in_parallel()
+ assert seen == ["ok"]
perform_transaction(cb)
def f2(r):
def cb(c):
@@ -284,6 +288,7 @@
assert not lib.in_nursery(p2)
assert lib.rawgetlong(p2, 0) == 9387987
perform_transaction(cb)
+ seen.append("ok")
r.leave_in_parallel()
run_parallel(f1, f2)
assert lib.getlong(pg, 0) == -6666
More information about the pypy-commit
mailing list