[pypy-commit] stmgc c8-new-page-handling: fix overwriting changes where we already have some modifications
Raemi
noreply at buildbot.pypy.org
Mon Sep 22 12:25:53 CEST 2014
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-new-page-handling
Changeset: r1404:ef65c8fd67f8
Date: 2014-09-22 12:26 +0200
http://bitbucket.org/pypy/stmgc/changeset/ef65c8fd67f8/
Log: fix overwriting changes where we already have some modifications
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -4,13 +4,42 @@
/* ############# signal handler ############# */
-static void _update_obj_from(int from_seg, object_t *obj)
+static void memcpy_to_accessible_pages(
+ int dst_segnum, object_t *dst_obj,
+ char *src, size_t len, uintptr_t only_page)
+{
+ /* XXX: optimize */
+
+ char *realobj = REAL_ADDRESS(get_segment_base(dst_segnum), dst_obj);
+ char *dst_end = realobj + len;
+ uintptr_t loc_addr = (uintptr_t)dst_obj;
+
+ dprintf(("memcpy_to_accessible_pages(%d, %p, %p, %lu, %lu)\n",
+ dst_segnum, dst_obj, src, len, only_page));
+
+ while (realobj != dst_end) {
+ if (get_page_status_in(dst_segnum, loc_addr / 4096UL) != PAGE_NO_ACCESS
+ && (only_page == -1 || only_page == loc_addr / 4096UL)) {
+ *realobj = *src;
+ }
+ realobj++;
+ loc_addr++;
+ src++;
+ }
+}
+
+
+static void _update_obj_from(int from_seg, object_t *obj, uintptr_t only_page)
{
/* updates 'obj' in our accessible pages from another segment's
- page or bk copy. (never touch PROT_NONE memory) */
+ page or bk copy. (never touch PROT_NONE memory)
+ only_page = -1 means update whole obj, only_page=pagenum means only
+ update memory in page 'pagenum'
+ */
/* XXXXXXX: are we sure everything is readable in from_seg??? */
size_t obj_size;
+ dprintf(("_update_obj_from(%d, %p)\n", from_seg, obj));
assert(get_priv_segment(from_seg)->privatization_lock);
/* look the obj up in the other segment's modified_old_objects to
@@ -24,7 +53,7 @@
obj_size = stmcb_size_rounded_up((struct object_s*)item->val);
memcpy_to_accessible_pages(STM_SEGMENT->segment_num, obj,
- (char*)item->val, obj_size);
+ (char*)item->val, obj_size, only_page);
release_modified_objs_lock(from_seg);
return;
@@ -36,7 +65,7 @@
memcpy_to_accessible_pages(STM_SEGMENT->segment_num, obj,
REAL_ADDRESS(get_segment_base(from_seg), obj),
- obj_size);
+ obj_size, only_page);
release_modified_objs_lock(from_seg);
}
@@ -45,7 +74,9 @@
static void copy_bk_objs_from(int from_segnum, uintptr_t pagenum)
{
/* looks at all bk copies of objects overlapping page 'pagenum' and
- copies to current segment (never touch PROT_NONE memory) */
+ copies to current segment (never touch PROT_NONE memory). */
+ dprintf(("copy_bk_objs_from(%d, %lu)\n", from_segnum, pagenum));
+
acquire_modified_objs_lock(from_segnum);
struct tree_s *tree = get_priv_segment(from_segnum)->modified_old_objects;
wlog_t *item;
@@ -58,18 +89,16 @@
/* XXX: should actually only write to pagenum, but we validate
afterwards anyway and abort in case we had modifications there */
memcpy_to_accessible_pages(STM_SEGMENT->segment_num,
- obj, (char*)bk_obj, obj_size);
-
- assert(obj->stm_flags & GCFLAG_WRITE_BARRIER); /* bk_obj never written */
+ obj, (char*)bk_obj, obj_size, pagenum);
}
} TREE_LOOP_END;
release_modified_objs_lock(from_segnum);
}
-static void update_page_from_to(
- uintptr_t pagenum, struct stm_commit_log_entry_s *from,
- struct stm_commit_log_entry_s *to)
+static void update_page_from_to(uintptr_t pagenum,
+ struct stm_commit_log_entry_s *from,
+ struct stm_commit_log_entry_s *to)
{
/* walk the commit log and update the page 'pagenum' until we reach
the same revision as our segment, or we reach the HEAD. */
@@ -90,7 +119,7 @@
object_t *obj;
size_t i = 0;
while ((obj = cl->written[i])) {
- _update_obj_from(cl->segment_num, obj);
+ _update_obj_from(cl->segment_num, obj, pagenum);
i++;
};
@@ -106,6 +135,8 @@
/* assumes page 'pagenum' is ACCESS_NONE, privatizes it,
and validates to newest revision */
+ dprintf(("bring_page_up_to_date(%lu), seg %d\n", pagenum, STM_SEGMENT->segment_num));
+
/* XXX: bad, but no deadlocks: */
acquire_all_privatization_locks();
@@ -241,7 +272,7 @@
object_t *obj;
size_t i = 0;
while ((obj = cl->written[i])) {
- _update_obj_from(cl->segment_num, obj);
+ _update_obj_from(cl->segment_num, obj, -1);
if (_stm_was_read(obj)) {
needs_abort = true;
diff --git a/c8/stm/pages.c b/c8/stm/pages.c
--- a/c8/stm/pages.c
+++ b/c8/stm/pages.c
@@ -73,24 +73,3 @@
volatile char *dummy = REAL_ADDRESS(get_segment_base(segnum), pagenum*4096UL);
*dummy = *dummy; /* force copy-on-write from shared page */
}
-
-
-static void memcpy_to_accessible_pages(
- int dst_segnum, object_t *dst_obj, char *src, size_t len)
-{
- /* XXX: optimize */
-
- char *realobj = REAL_ADDRESS(get_segment_base(dst_segnum), dst_obj);
- char *dst_end = realobj + len;
- uintptr_t loc_addr = (uintptr_t)dst_obj;
-
- dprintf(("memcpy_to_accessible_pages(%d, %p, %p, %lu)\n", dst_segnum, dst_obj, src, len));
-
- while (realobj != dst_end) {
- if (get_page_status_in(dst_segnum, loc_addr / 4096UL) != PAGE_NO_ACCESS)
- *realobj = *src;
- realobj++;
- loc_addr++;
- src++;
- }
-}
diff --git a/c8/stm/pages.h b/c8/stm/pages.h
--- a/c8/stm/pages.h
+++ b/c8/stm/pages.h
@@ -46,7 +46,6 @@
static void pages_initialize_shared_for(long segnum, uintptr_t pagenum, uintptr_t count);
static void page_privatize_in(int segnum, uintptr_t pagenum);
-static void memcpy_to_accessible_pages(int dst_segnum, object_t *dst_obj, char *src, size_t len);
More information about the pypy-commit
mailing list