Author: Remi Meier <remi.me...@inf.ethz.ch> Branch: Changeset: r1342:d02e51a1b9e1 Date: 2014-09-03 16:45 +0200 http://bitbucket.org/pypy/stmgc/changeset/d02e51a1b9e1/
Log: start with some signal handling diff --git a/c8/stm/core.c b/c8/stm/core.c --- a/c8/stm/core.c +++ b/c8/stm/core.c @@ -2,9 +2,23 @@ # error "must be compiled via stmgc.c" #endif +#include <signal.h> + + +/* ############# signal handler ############# */ + +void _signal_handler(int sig, siginfo_t *siginfo, void *context) +{ + + if (siginfo->si_addr == NULL) { + /* send to GDB */ + kill(getpid(), SIGINT); + } +} /* ############# commit log ############# */ + void _dbg_print_commit_log() { struct stm_commit_log_entry_s *cl = &commit_log_root; @@ -90,6 +104,26 @@ stm_read(obj); + /* make other segments trap if accessing this object */ + uintptr_t first_page = ((uintptr_t)obj) / 4096UL; + char *realobj; + size_t obj_size; + uintptr_t i, end_page; + + 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) + continue; + + char *segment_base = get_segment_base(i); + mprotect(segment_base + first_page * 4096, + (end_page - first_page + 1) * 4096, PROT_NONE); + dprintf(("prot %lu, len=%lu in seg %d\n", first_page, (end_page - first_page + 1), i)); + } + LIST_APPEND(STM_PSEGMENT->modified_old_objects, obj); LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj); @@ -162,66 +196,6 @@ /************************************************************/ -static void _page_wise_synchronize_object_now(object_t *obj) -{ - uintptr_t start = (uintptr_t)obj; - uintptr_t first_page = start / 4096UL; - - char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); - ssize_t obj_size = stmcb_size_rounded_up((struct object_s *)realobj); - assert(obj_size >= 16); - uintptr_t end = start + obj_size; - uintptr_t last_page = (end - 1) / 4096UL; - long i, myself = STM_SEGMENT->segment_num; - - for (; first_page <= last_page; first_page++) { - - uintptr_t copy_size; - if (first_page == last_page) { - /* this is the final fragment */ - copy_size = end - start; - } - else { - /* this is a non-final fragment, going up to the - page's end */ - copy_size = 4096 - (start & 4095); - } - /* double-check that the result fits in one page */ - assert(copy_size > 0); - assert(copy_size + (start & 4095) <= 4096); - - char *dst, *src; - src = REAL_ADDRESS(STM_SEGMENT->segment_base, start); - for (i = 0; i < NB_SEGMENTS; i++) { - if (i == myself) - continue; - - dst = REAL_ADDRESS(get_segment_base(i), start); - if (is_private_page(i, first_page)) { - /* The page is a private page. We need to diffuse this - fragment of object from the shared page to this private - page. */ - if (copy_size == 4096) - pagecopy(dst, src); - else - memcpy(dst, src, copy_size); - } - else { - assert(!memcmp(dst, src, copy_size)); /* same page */ - } - } - - start = (start + 4096) & ~4095; - } -} - -void _push_obj_to_other_segments(object_t *obj) -{ - acquire_privatization_lock(); - _page_wise_synchronize_object_now(obj); - release_privatization_lock(); -} - static void _finish_transaction() { stm_thread_local_t *tl = STM_SEGMENT->running_thread; diff --git a/c8/stm/core.h b/c8/stm/core.h --- a/c8/stm/core.h +++ b/c8/stm/core.h @@ -20,7 +20,7 @@ #define MAP_PAGES_FLAGS (MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE) #define NB_NURSERY_PAGES (STM_GC_NURSERY/4) -#define TOTAL_MEMORY (NB_PAGES * 4096UL * (1 + NB_SEGMENTS)) +#define TOTAL_MEMORY (NB_PAGES * 4096UL * NB_SEGMENTS) #define READMARKER_END ((NB_PAGES * 4096UL) >> 4) #define FIRST_OBJECT_PAGE ((READMARKER_END + 4095) / 4096UL) #define FIRST_NURSERY_PAGE FIRST_OBJECT_PAGE diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c --- a/c8/stm/gcpage.c +++ b/c8/stm/gcpage.c @@ -15,7 +15,7 @@ static void setup_N_pages(char *pages_addr, uint64_t num) { - pages_initialize_private((pages_addr - stm_object_pages) / 4096UL, num); + pages_initialize_shared((pages_addr - stm_object_pages) / 4096UL, num); } diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c --- a/c8/stm/nursery.c +++ b/c8/stm/nursery.c @@ -139,9 +139,6 @@ _collect_now(obj); - /* XXX: only if commit now and only for big objs */ - _push_obj_to_other_segments(obj); - /* the list could have moved while appending */ lst = STM_PSEGMENT->objects_pointing_to_nursery; } diff --git a/c8/stm/pages.c b/c8/stm/pages.c --- a/c8/stm/pages.c +++ b/c8/stm/pages.c @@ -16,31 +16,55 @@ /************************************************************/ +static void d_remap_file_pages(char *addr, size_t size, ssize_t pgoff) +{ + dprintf(("remap_file_pages: 0x%lx bytes: (seg%ld %p) --> (seg%ld %p)\n", + (long)size, + (long)((addr - stm_object_pages) / 4096UL) / NB_PAGES, + (void *)((addr - stm_object_pages) % (4096UL * NB_PAGES)), + (long)pgoff / NB_PAGES, + (void *)((pgoff % NB_PAGES) * 4096UL))); + assert(size % 4096 == 0); + assert(size <= TOTAL_MEMORY); + assert(((uintptr_t)addr) % 4096 == 0); + assert(addr >= stm_object_pages); + assert(addr <= stm_object_pages + TOTAL_MEMORY - size); + assert(pgoff >= 0); + assert(pgoff <= (TOTAL_MEMORY - size) / 4096UL); -static void pages_initialize_private(uintptr_t pagenum, uintptr_t count) + /* assert remappings follow the rule that page N in one segment + can only be remapped to page N in another segment */ + assert(((addr - stm_object_pages) / 4096UL - pgoff) % NB_PAGES == 0); + +#ifdef USE_REMAP_FILE_PAGES + int res = remap_file_pages(addr, size, 0, pgoff, 0); + if (UNLIKELY(res < 0)) + stm_fatalerror("remap_file_pages: %m"); +#else + char *res = mmap(addr, size, + PROT_READ | PROT_WRITE, + (MAP_PAGES_FLAGS & ~MAP_ANONYMOUS) | MAP_FIXED, + stm_object_pages_fd, pgoff * 4096UL); + if (UNLIKELY(res != addr)) + stm_fatalerror("mmap (remapping page): %m"); +#endif +} + + +static void pages_initialize_shared(uintptr_t pagenum, uintptr_t count) { - dprintf(("pages_initialize_private: 0x%ld - 0x%ld\n", pagenum, + /* call remap_file_pages() to make all pages in the range(pagenum, + pagenum+count) refer to the same physical range of pages from + segment 0. */ + dprintf(("pages_initialize_shared: 0x%ld - 0x%ld\n", pagenum, pagenum + count)); assert(pagenum < NB_PAGES); if (count == 0) return; - - long i; - for (i = 0; i < NB_SEGMENTS; i++) { - spinlock_acquire(get_priv_segment(i)->privatization_lock); - } - - while (count-->0) { - for (i = 0; i < NB_SEGMENTS; i++) { - uint64_t bitmask = 1UL << i; - volatile struct page_shared_s *ps = (volatile struct page_shared_s *) - &pages_privatized[pagenum + count - PAGE_FLAG_START]; - - ps->by_segment |= bitmask; - } - } - - for (i = NB_SEGMENTS-1; i >= 0; i--) { - spinlock_release(get_priv_segment(i)->privatization_lock); + uintptr_t i; + for (i = 1; i < NB_SEGMENTS; i++) { + char *segment_base = get_segment_base(i); + d_remap_file_pages(segment_base + pagenum * 4096UL, + count * 4096UL, pagenum); } } diff --git a/c8/stm/pages.h b/c8/stm/pages.h --- a/c8/stm/pages.h +++ b/c8/stm/pages.h @@ -20,8 +20,7 @@ static struct page_shared_s pages_privatized[PAGE_FLAG_END - PAGE_FLAG_START]; -static void pages_initialize_private(uintptr_t pagenum, uintptr_t count); - +static void pages_initialize_shared(uintptr_t pagenum, uintptr_t count); static inline bool is_private_page(long segnum, uintptr_t pagenum) { diff --git a/c8/stm/setup.c b/c8/stm/setup.c --- a/c8/stm/setup.c +++ b/c8/stm/setup.c @@ -2,6 +2,7 @@ # error "must be compiled via stmgc.c" #endif +#include <signal.h> #ifdef USE_REMAP_FILE_PAGES static char *setup_mmap(char *reason, int *ignored) @@ -67,9 +68,32 @@ mprotect(segment_base + 8192, (FIRST_READMARKER_PAGE - 2) * 4096UL, PROT_NONE); + + if (i != 0) { + /* let's give all pages to segment 0 at first and make them + write-inaccessible everywhere else */ + mprotect(segment_base + END_NURSERY_PAGE * 4096, + (NB_PAGES - END_NURSERY_PAGE) * 4096, + PROT_READ); + } } } +static void setup_signal_handler(void) +{ + struct sigaction act; + memset(&act, 0, sizeof(act)); + + act.sa_sigaction = &_signal_handler; + /* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */ + act.sa_flags = SA_SIGINFO; + + if (sigaction(SIGSEGV, &act, NULL) < 0) { + perror ("sigaction"); + abort(); + } +} + void stm_setup(void) { /* Check that some values are acceptable */ @@ -89,6 +113,7 @@ stm_object_pages = setup_mmap("initial stm_object_pages mmap()", &stm_object_pages_fd); setup_protection_settings(); + setup_signal_handler(); long i; for (i = 0; i < NB_SEGMENTS; i++) { diff --git a/c8/test/support.py b/c8/test/support.py --- a/c8/test/support.py +++ b/c8/test/support.py @@ -46,7 +46,6 @@ char *_stm_get_segment_base(long index); bool _stm_in_transaction(stm_thread_local_t *tl); int _stm_get_flags(object_t *obj); -void _push_obj_to_other_segments(object_t *obj); object_t *_stm_allocate_old(ssize_t size_rounded_up); long stm_can_move(object_t *obj); @@ -244,14 +243,12 @@ o = lib._stm_allocate_old(size) tid = 42 + size lib._set_type_id(o, tid) - lib._push_obj_to_other_segments(o) return o def stm_allocate_old_refs(n): o = lib._stm_allocate_old(HDR + n * WORD) tid = 421420 + n lib._set_type_id(o, tid) - lib._push_obj_to_other_segments(o) return o def stm_allocate(size): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit