[pypy-commit] stmgc default: fix the read-write conflict location in case of a conflict between
arigo
noreply at buildbot.pypy.org
Mon Feb 9 19:11:14 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r1616:65a89cd8a6c0
Date: 2015-02-09 19:11 +0100
http://bitbucket.org/pypy/stmgc/changeset/65a89cd8a6c0/
Log: fix the read-write conflict location in case of a conflict between a
stmdict.keys() and a write of an entry
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -435,26 +435,31 @@
char *remote_base = get_segment_base(i);
object_t *conflicting_obj;
+ uintptr_t j, limit;
+ struct list_s *lst;
- LIST_FOREACH_R(
- STM_PSEGMENT->modified_old_objects,
- object_t * /*item*/,
- ({
- if (was_read_remote(remote_base, item)) {
- conflicting_obj = item;
- goto found_conflict;
- }
- }));
+ /* Look in forward order: this is an attempt to report the _first_
+ write that conflicts with another segment's reads
+ */
+ lst = STM_PSEGMENT->modified_old_objects;
+ limit = list_count(lst);
+ for (j = 0; j < limit; j++) {
+ object_t *obj = (object_t *)list_item(lst, j);
+ if (was_read_remote(remote_base, obj)) {
+ conflicting_obj = obj;
+ goto found_conflict;
+ }
+ }
- LIST_FOREACH_R(
- STM_PSEGMENT->modified_old_hashtables,
- object_t * /*item*/,
- ({
- if (was_read_remote(remote_base, item)) {
- conflicting_obj = item;
- goto found_conflict;
- }
- }));
+ lst = STM_PSEGMENT->modified_old_hashtables;
+ limit = list_count(lst);
+ for (j = 0; j < limit; j += 2) {
+ object_t *hobj = (object_t *)list_item(lst, j);
+ if (was_read_remote(remote_base, hobj)) {
+ conflicting_obj = (object_t *)list_item(lst, j + 1);
+ goto found_conflict;
+ }
+ }
continue;
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -96,7 +96,8 @@
uintptr_t modified_old_objects_markers_num_old;
/* This list contains all old hashtables that have entries that we
- modified. Note that several transactions can all commit if
+ modified. It's actually a list of pairs hashtable/sample_entry.
+ Note that several transactions can all commit if
they have the same hashtable listed here. The point of this
list is only that if another segment does a global "read" of
the hashtable (stm_hashtable_list), then it conflicts with this
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -475,26 +475,13 @@
}
}
+static void clean_up_segment_lists(void)
+{
#pragma push_macro("STM_PSEGMENT")
#pragma push_macro("STM_SEGMENT")
#undef STM_PSEGMENT
#undef STM_SEGMENT
-static void remove_objects_that_die(struct list_s *lst)
-{
- if (lst != NULL) {
- uintptr_t n = list_count(lst);
- while (n > 0) {
- object_t *obj = (object_t *)list_item(lst, --n);
- if (!mark_visited_test(obj)) {
- list_set_item(lst, n, list_pop_item(lst));
- }
- }
- }
-}
-
-static void clean_up_segment_lists(void)
-{
long i;
for (i = 1; i <= NB_SEGMENTS; i++) {
struct stm_priv_segment_info_s *pseg = get_priv_segment(i);
@@ -553,14 +540,39 @@
}));
list_clear(lst);
- /* Remove from 'large_overflow_objects' and 'modified_old_hashtables'
- all objects that die */
- remove_objects_that_die(pseg->large_overflow_objects);
- remove_objects_that_die(pseg->modified_old_hashtables);
+ /* Remove from 'large_overflow_objects' all objects that die */
+ lst = pseg->large_overflow_objects;
+ if (lst != NULL) {
+ uintptr_t n = list_count(lst);
+ while (n > 0) {
+ object_t *obj = (object_t *)list_item(lst, --n);
+ if (!mark_visited_test(obj))
+ list_set_item(lst, n, list_pop_item(lst));
+ }
+ }
+
+ /* Remove from 'modified_old_hashtables' all old hashtables that
+ die, but keeping the order */
+ {
+ lst = pseg->modified_old_hashtables;
+ uintptr_t j, k = 0, limit = list_count(lst);
+ for (j = 0; j < limit; j += 2) {
+ object_t *hobj = (object_t *)list_item(lst, j);
+ if (mark_visited_test(hobj)) {
+ /* hobj does not die */
+ if (j != k) {
+ list_set_item(lst, k, (uintptr_t)hobj);
+ list_set_item(lst, k + 1, list_item(lst, j + 1));
+ }
+ k += 2;
+ }
+ }
+ lst->count = k;
+ }
}
-}
#pragma pop_macro("STM_SEGMENT")
#pragma pop_macro("STM_PSEGMENT")
+}
static inline bool largemalloc_keep_object_at(char *data)
{
diff --git a/c7/stm/hashtable.c b/c7/stm/hashtable.c
--- a/c7/stm/hashtable.c
+++ b/c7/stm/hashtable.c
@@ -358,12 +358,13 @@
avoid them --- at least the list should never be longer
than 'modified_old_objects'. */
i = list_count(STM_PSEGMENT->modified_old_hashtables);
- if (i > 0 && list_item(STM_PSEGMENT->modified_old_hashtables, i - 1)
+ if (i > 0 && list_item(STM_PSEGMENT->modified_old_hashtables, i - 2)
== (uintptr_t)hobj) {
/* already added */
}
else {
- LIST_APPEND(STM_PSEGMENT->modified_old_hashtables, hobj);
+ LIST_APPEND2(STM_PSEGMENT->modified_old_hashtables,
+ hobj, entry);
}
}
}
diff --git a/c7/stm/list.h b/c7/stm/list.h
--- a/c7/stm/list.h
+++ b/c7/stm/list.h
@@ -45,6 +45,9 @@
return lst;
}
+#define LIST_APPEND2(lst, e1, e2) ((lst) = list_append2((lst), \
+ (uintptr_t)(e1), (uintptr_t)(e2)))
+
static inline void list_clear(struct list_s *lst)
{
More information about the pypy-commit
mailing list