[pypy-commit] stmgc card-marking: wip
Raemi
noreply at buildbot.pypy.org
Mon May 19 17:38:21 CEST 2014
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: card-marking
Changeset: r1215:cde500a7d39e
Date: 2014-05-19 17:20 +0200
http://bitbucket.org/pypy/stmgc/changeset/cde500a7d39e/
Log: wip
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -79,9 +79,7 @@
void _stm_write_slowpath(object_t *obj, uintptr_t offset)
{
- assert(IMPLY(!(obj->stm_flags & GCFLAG_HAS_CARDS),
- offset == 0));
-
+ assert(IMPLY(!(obj->stm_flags & GCFLAG_HAS_CARDS), offset == 0));
assert(_seems_to_be_running_transaction());
assert(!_is_young(obj));
assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
@@ -100,16 +98,18 @@
'modified_old_objects' (but, because it had GCFLAG_WRITE_BARRIER,
not in 'objects_pointing_to_nursery'). We'll detect this case
by finding that we already own the write-lock. */
- uintptr_t lock_idx = get_write_lock_idx((uintptr_t)obj);
+ bool lock_whole = offset == 0;
+ uintptr_t base_lock_idx = get_write_lock_idx((uintptr_t)obj);
+ //uintptr_t card_lock_idx = get_write_lock_idx((uintptr_t)obj + offset);
uint8_t lock_num = STM_PSEGMENT->write_lock_num;
- assert(lock_idx < sizeof(write_locks));
+ assert(base_lock_idx < sizeof(write_locks));
retry:
- if (write_locks[lock_idx] == 0) {
+ if (write_locks[base_lock_idx] == 0) {
/* A lock to prevent reading garbage from
lookup_other_thread_recorded_marker() */
acquire_marker_lock(STM_SEGMENT->segment_base);
- if (UNLIKELY(!__sync_bool_compare_and_swap(&write_locks[lock_idx],
+ if (UNLIKELY(!__sync_bool_compare_and_swap(&write_locks[base_lock_idx],
0, lock_num))) {
release_marker_lock(STM_SEGMENT->segment_base);
goto retry;
@@ -159,7 +159,7 @@
}
}
}
- else if (write_locks[lock_idx] == lock_num) {
+ else if (write_locks[base_lock_idx] == lock_num) {
OPT_ASSERT(STM_PSEGMENT->objects_pointing_to_nursery != NULL);
#ifdef STM_TESTS
bool found = false;
@@ -171,33 +171,47 @@
else {
/* call the contention manager, and then retry (unless we were
aborted). */
- write_write_contention_management(lock_idx, obj);
+ write_write_contention_management(base_lock_idx, obj);
goto retry;
}
/* A common case for write_locks[] that was either 0 or lock_num:
- we need to add the object to 'objects_pointing_to_nursery'
- if there is such a list. */
- if (STM_PSEGMENT->objects_pointing_to_nursery != NULL) {
- dprintf_test(("write_slowpath %p -> old obj_to_nurs\n", obj));
- LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+ we need to add the object to the appropriate list if there is one. */
+ if (lock_whole) {
+ if (STM_PSEGMENT->objects_pointing_to_nursery != NULL) {
+ dprintf_test(("write_slowpath %p -> old obj_to_nurs\n", obj));
+ LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+ }
+
+ /* check that we really have a private page */
+ assert(is_private_page(STM_SEGMENT->segment_num,
+ ((uintptr_t)obj) / 4096));
+ /* check that so far all copies of the object have the flag */
+ check_flag_write_barrier(obj);
+
+ /* remove GCFLAG_WRITE_BARRIER if we succeeded in getting the base
+ write-lock (not for card marking). */
+ assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
+ obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
+
+ /* for sanity, check again that all other segment copies of this
+ object still have the flag (so privatization worked) */
+ check_flag_write_barrier(obj);
+
+ } else { /* card marking case */
+
+ if (!(obj->stm_flags & GCFLAG_CARDS_SET)) {
+ /* not yet in the list (may enter here multiple times) */
+ if (STM_PSEGMENT->old_objects_with_cards != NULL) {
+ LIST_APPEND(STM_PSEGMENT->old_objects_with_cards, obj);
+ }
+ obj->stm_flags |= GCFLAG_CARDS_SET;
+ }
+
+ /* check that we really have a private page */
+ assert(is_private_page(STM_SEGMENT->segment_num,
+ ((uintptr_t)obj + offset) / 4096));
}
-
- /* check that we really have a private page */
- assert(is_private_page(STM_SEGMENT->segment_num,
- ((uintptr_t)obj) / 4096));
-
- /* check that so far all copies of the object have the flag */
- check_flag_write_barrier(obj);
-
- /* remove GCFLAG_WRITE_BARRIER, but only if we succeeded in
- getting the write-lock */
- assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
- obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
-
- /* for sanity, check again that all other segment copies of this
- object still have the flag (so privatization worked) */
- check_flag_write_barrier(obj);
}
static void reset_transaction_read_version(void)
More information about the pypy-commit
mailing list