Author: Remi Meier <remi.me...@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); _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit