[pypy-commit] stmgc default: Subtle race condition
arigo
noreply at buildbot.pypy.org
Sun Feb 8 22:14:47 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r1611:005668d99755
Date: 2015-02-08 22:15 +0100
http://bitbucket.org/pypy/stmgc/changeset/005668d99755/
Log: Subtle race condition
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -312,6 +312,11 @@
FIRST_READMARKER_PAGE * 4096UL);
dprintf(("reset_transaction_read_version: %p %ld\n", readmarkers,
(long)(NB_READMARKER_PAGES * 4096UL)));
+
+ /* see hashtable.c for why we need the privatization lock here
+ (grep for reset_transaction_read_version)
+ */
+ acquire_privatization_lock();
if (mmap(readmarkers, NB_READMARKER_PAGES * 4096UL,
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PAGES_FLAGS, -1, 0) != readmarkers) {
@@ -322,6 +327,7 @@
memset(readmarkers, 0, NB_READMARKER_PAGES * 4096UL);
}
STM_SEGMENT->transaction_read_version = 1;
+ release_privatization_lock();
}
static uint64_t _global_start_time = 0;
diff --git a/c7/stm/hashtable.c b/c7/stm/hashtable.c
--- a/c7/stm/hashtable.c
+++ b/c7/stm/hashtable.c
@@ -299,16 +299,28 @@
*/
/* First fetch the read marker of 'hashtableobj' in all
- segments, before allocate_outside_nursery_large()
- which might trigger a GC */
+ segments, before allocate_outside_nursery_large() which
+ might trigger a GC. Synchronization guarantee: if
+ stm_read(hobj) in stm_hashtable_list() has set the read
+ marker, then it did synchronize with us here by
+ acquiring and releasing this hashtable' lock. However,
+ the interval of time between reading the readmarkers of
+ hobj and copying them to the new entry object might be
+ enough for the other threads to do anything, including
+ a reset_transaction_read_version(), so that we might in
+ theory write bogus read markers that are not valid any
+ more. To prevent this, reset_transaction_read_version()
+ acquires the privatization_lock too.
+ */
long j;
uint8_t readmarkers[NB_SEGMENTS];
+
+ acquire_privatization_lock();
for (j = 1; j <= NB_SEGMENTS; j++) {
readmarkers[j - 1] = get_read_marker(get_segment_base(j),
hashtableobj)->rm;
}
- acquire_privatization_lock();
char *p = allocate_outside_nursery_large(
sizeof(stm_hashtable_entry_t));
entry = (stm_hashtable_entry_t *)(p - stm_object_pages);
@@ -323,12 +335,12 @@
e->object = NULL;
}
hashtable->additions += 0x100;
- release_privatization_lock();
for (j = 1; j <= NB_SEGMENTS; j++) {
get_read_marker(get_segment_base(j), (object_t *)entry)->rm =
readmarkers[j - 1];
}
+ release_privatization_lock();
}
write_fence(); /* make sure 'entry' is fully initialized here */
table->items[i] = entry;
More information about the pypy-commit
mailing list