[pypy-commit] stmgc c7-refactor: Fix the GCFLAG_WRITE_BARRIER_CALLED when committing
arigo
noreply at buildbot.pypy.org
Sun Feb 16 09:49:09 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r747:1c1739135bd5
Date: 2014-02-16 09:47 +0100
http://bitbucket.org/pypy/stmgc/changeset/1c1739135bd5/
Log: Fix the GCFLAG_WRITE_BARRIER_CALLED when committing
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -62,6 +62,7 @@
/* add the write-barrier-already-called flag ONLY if we succeeded in
getting the write-lock */
+ assert(!(obj->stm_flags & GCFLAG_WRITE_BARRIER_CALLED));
obj->stm_flags |= GCFLAG_WRITE_BARRIER_CALLED;
LIST_APPEND(STM_PSEGMENT->modified_objects, obj);
}
@@ -177,14 +178,21 @@
get_segment(remote_num)->transaction_read_version));
}
- /* clear the write-lock */
+ /* clear the write-lock (note that this runs with all other
+ threads paused, so no need to be careful about ordering) */
uintptr_t lock_idx = (((uintptr_t)item) >> 4) - READMARKER_START;
assert(write_locks[lock_idx] == STM_PSEGMENT->write_lock_num);
write_locks[lock_idx] = 0;
+ /* remove again the WRITE_BARRIER_CALLED flag */
+ assert(item->stm_flags & GCFLAG_WRITE_BARRIER_CALLED);
+ item->stm_flags &= ~GCFLAG_WRITE_BARRIER_CALLED;
+
+ /* copy the modified object to the other segment */
char *src = REAL_ADDRESS(local_base, item);
+ char *dst = REAL_ADDRESS(remote_base, item);
ssize_t size = stmcb_size_rounded_up((struct object_s *)src);
- memcpy(REAL_ADDRESS(remote_base, item), src, size);
+ memcpy(dst, src, size);
}));
list_clear(STM_PSEGMENT->modified_objects);
@@ -250,18 +258,27 @@
STM_PSEGMENT->modified_objects,
object_t * /*item*/,
({
+ /* all objects in 'modified_objects' have this flag */
+ assert(item->stm_flags & GCFLAG_WRITE_BARRIER_CALLED);
+
/* memcpy in the opposite direction than
push_modified_to_other_segments() */
char *src = REAL_ADDRESS(remote_base, item);
+ char *dst = REAL_ADDRESS(local_base, item);
ssize_t size = stmcb_size_rounded_up((struct object_s *)src);
- memcpy(REAL_ADDRESS(local_base, item), src, size);
+ memcpy(dst, src, size);
- /* copying from the other thread re-added the
- WRITE_BARRIER flag */
- //assert(item->stm_flags & GCFLAG_WRITE_BARRIER); --- XXX
+ /* copying from the other segment removed again the
+ WRITE_BARRIER_CALLED flag */
+ assert(!(item->stm_flags & GCFLAG_WRITE_BARRIER_CALLED));
/* write all changes to the object before we release the
- write lock below */
+ write lock below. This is needed because we need to
+ ensure that if the write lock is not set, another thread
+ can get it and then change 'src' in parallel. The
+ write_fence() ensures in particular that 'src' has been
+ fully read before we release the lock: reading it
+ is necessary to write 'dst'. */
write_fence();
/* clear the write-lock */
More information about the pypy-commit
mailing list