Author: Remi Meier <remi.me...@inf.ethz.ch> Branch: Changeset: r1351:419893208d27 Date: 2014-09-04 16:11 +0200 http://bitbucket.org/pypy/stmgc/changeset/419893208d27/
Log: some refactoring diff --git a/c8/stm/core.c b/c8/stm/core.c --- a/c8/stm/core.c +++ b/c8/stm/core.c @@ -29,7 +29,8 @@ calls page_copy() and traps */ /* XXX: mprotect is not reentrant and interruptible by signals, so it needs additional synchronisation.*/ - mprotect(seg_base + pagenum * 4096UL, 4096, PROT_READ|PROT_WRITE); + pages_set_protection(segnum, pagenum, 1, PROT_READ|PROT_WRITE); + page_privatize(pagenum); /* XXX: ... what can go wrong when we abort from inside @@ -74,6 +75,7 @@ volatile struct stm_commit_log_entry_s *cl = (volatile struct stm_commit_log_entry_s *) STM_PSEGMENT->last_commit_log_entry; + bool needs_abort = false; /* Don't check 'cl'. This entry is already checked */ while ((cl = cl->next)) { size_t i = 0; @@ -81,12 +83,10 @@ object_t *obj; while ((obj = cl->written[i])) { - _update_obj_from(cl->segment_num, obj); - if (_stm_was_read(obj)) { - free(free_if_abort); - stm_abort_transaction(); + if (!needs_abort &&_stm_was_read(obj)) { + needs_abort = true; } i++; @@ -95,6 +95,11 @@ /* last fully validated entry */ STM_PSEGMENT->last_commit_log_entry = (struct stm_commit_log_entry_s *)cl; } + + if (needs_abort) { + free(free_if_abort); + stm_abort_transaction(); + } } static struct stm_commit_log_entry_s *_create_commit_log_entry() @@ -156,22 +161,27 @@ char *realobj; size_t obj_size; uintptr_t i, end_page; + int my_segnum = STM_SEGMENT->segment_num; realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); obj_size = stmcb_size_rounded_up((struct object_s *)realobj); end_page = (((uintptr_t)obj) + obj_size - 1) / 4096UL; for (i = 0; i < NB_SEGMENTS; i++) { - if (i == STM_SEGMENT->segment_num) + if (i == my_segnum) + continue; + if (!is_readable_page(i, first_page)) continue; /* XXX: only do it if not already PROT_NONE */ char *segment_base = get_segment_base(i); - mprotect(segment_base + first_page * 4096, - (end_page - first_page + 1) * 4096, PROT_NONE); + pages_set_protection(i, first_page, end_page - first_page + 1, + PROT_NONE); dprintf(("prot %lu, len=%lu in seg %lu\n", first_page, (end_page - first_page + 1), i)); } + acquire_modified_objs_lock(my_segnum); tree_insert(STM_PSEGMENT->modified_old_objects, (uintptr_t)obj, 0); + release_modified_objs_lock(my_segnum); LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj); obj->stm_flags &= ~GCFLAG_WRITE_BARRIER; @@ -261,7 +271,9 @@ minor_collection(1); struct stm_commit_log_entry_s* entry = _validate_and_add_to_commit_log(); + acquire_modified_objs_lock(STM_SEGMENT->segment_num); /* XXX:discard backup copies */ + release_modified_objs_lock(STM_SEGMENT->segment_num); s_mutex_lock(); diff --git a/c8/stm/core.h b/c8/stm/core.h --- a/c8/stm/core.h +++ b/c8/stm/core.h @@ -48,6 +48,7 @@ struct stm_priv_segment_info_s { struct stm_segment_info_s pub; + uint8_t modified_objs_lock; struct tree_s *modified_old_objects; struct list_s *objects_pointing_to_nursery; uint8_t privatization_lock; @@ -127,3 +128,17 @@ &STM_PSEGMENT->privatization_lock); spinlock_release(*lock); } + +static inline void acquire_modified_objs_lock(int segnum) +{ + uint8_t *lock = (uint8_t *)REAL_ADDRESS(get_segment_base(segnum), + &STM_PSEGMENT->modified_objs_lock); + spinlock_acquire(*lock); +} + +static inline void release_modified_objs_lock(int segnum) +{ + uint8_t *lock = (uint8_t *)REAL_ADDRESS(get_segment_base(segnum), + &STM_PSEGMENT->modified_objs_lock); + spinlock_release(*lock); +} diff --git a/c8/stm/pages.c b/c8/stm/pages.c --- a/c8/stm/pages.c +++ b/c8/stm/pages.c @@ -1,7 +1,7 @@ #ifndef _STM_CORE_H_ # error "must be compiled via stmgc.c" #endif - +#include <signal.h> /************************************************************/ @@ -67,12 +67,28 @@ d_remap_file_pages(segment_base + pagenum * 4096UL, count * 4096UL, pagenum); } + + for (i = 0; i < NB_SEGMENTS; i++) { + uint64_t bitmask = 1UL << i; + uintptr_t amount = count; + while (amount-->0) { + volatile struct page_shared_s *ps = (volatile struct page_shared_s *) + &pages_readable[pagenum + amount - PAGE_FLAG_START]; + if (i == 0) { + /* readable */ + ps->by_segment |= bitmask; + } else { + /* not readable (ensured in setup.c) */ + ps->by_segment &= ~bitmask; + } + } + } } static void page_privatize(uintptr_t pagenum) { /* check this thread's 'pages_privatized' bit */ - uint64_t bitmask = 1UL << (STM_SEGMENT->segment_num - 1); + uint64_t bitmask = 1UL << STM_SEGMENT->segment_num; volatile struct page_shared_s *ps = (volatile struct page_shared_s *) &pages_privatized[pagenum - PAGE_FLAG_START]; if (ps->by_segment & bitmask) { @@ -103,3 +119,27 @@ spinlock_release(get_priv_segment(i)->privatization_lock); } } + +static void pages_set_protection(int segnum, uintptr_t pagenum, + uintptr_t count, int prot) +{ + char *addr = get_segment_base(segnum) + pagenum * 4096UL; + mprotect(addr, count * 4096UL, prot); + + long i; + for (i = 0; i < NB_SEGMENTS; i++) { + uint64_t bitmask = 1UL << i; + uintptr_t amount = count; + while (amount-->0) { + volatile struct page_shared_s *ps = (volatile struct page_shared_s *) + &pages_readable[pagenum + amount - PAGE_FLAG_START]; + if (prot == PROT_NONE) { + /* not readable */ + ps->by_segment &= ~bitmask; + } else { + assert(prot == (PROT_READ|PROT_WRITE)); + ps->by_segment |= bitmask; + } + } + } +} diff --git a/c8/stm/pages.h b/c8/stm/pages.h --- a/c8/stm/pages.h +++ b/c8/stm/pages.h @@ -19,10 +19,12 @@ }; static struct page_shared_s pages_privatized[PAGE_FLAG_END - PAGE_FLAG_START]; +static struct page_shared_s pages_readable[PAGE_FLAG_END - PAGE_FLAG_START]; static void pages_initialize_shared(uintptr_t pagenum, uintptr_t count); static void page_privatize(uintptr_t pagenum); - +static void pages_set_protection(int segnum, uintptr_t pagenum, + uintptr_t count, int prot); static inline bool is_private_page(long segnum, uintptr_t pagenum) { @@ -30,3 +32,10 @@ uint64_t bitmask = 1UL << segnum; return (pages_privatized[pagenum - PAGE_FLAG_START].by_segment & bitmask); } + +static inline bool is_readable_page(long segnum, uintptr_t pagenum) +{ + assert(pagenum >= PAGE_FLAG_START); + uint64_t bitmask = 1UL << segnum; + return (pages_readable[pagenum - PAGE_FLAG_START].by_segment & bitmask); +} diff --git a/c8/stm/setup.c b/c8/stm/setup.c --- a/c8/stm/setup.c +++ b/c8/stm/setup.c @@ -75,6 +75,8 @@ mprotect(segment_base + END_NURSERY_PAGE * 4096, (NB_PAGES - END_NURSERY_PAGE) * 4096, PROT_NONE); + /* pages_initialize_shared() makes sure pages_readable + is initialized correctly */ } } } _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit