[pypy-commit] stmgc c8-new-page-handling: some progress
Raemi
noreply at buildbot.pypy.org
Thu Sep 18 16:54:19 CEST 2014
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-new-page-handling
Changeset: r1392:5e2059e06b18
Date: 2014-09-18 16:54 +0200
http://bitbucket.org/pypy/stmgc/changeset/5e2059e06b18/
Log: some progress
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -39,9 +39,8 @@
char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
uintptr_t pagenum = (uintptr_t)obj / 4096UL;
- OPT_ASSERT(!is_shared_log_page(pagenum));
- assert(is_private_log_page_in(STM_SEGMENT->segment_num, pagenum));
- assert(is_private_log_page_in(from_seg, pagenum));
+ assert(get_page_status_in(from_seg, pagenum) != PAGE_NO_ACCESS);
+ assert(get_page_status_in(STM_SEGMENT->segment_num, pagenum) != PAGE_NO_ACCESS);
/* look the obj up in the other segment's modified_old_objects to
get its backup copy: */
@@ -218,18 +217,17 @@
uintptr_t i;
int my_segnum = STM_SEGMENT->segment_num;
- assert(is_shared_log_page(pagenum));
- char *src = (char*)(get_virt_page_of(0, pagenum) * 4096UL);
+ XXX();
+ //assert(is_shared_log_page(pagenum));
+ /* char *src = (char*)(get_virt_page_of(0, pagenum) * 4096UL); */
- for (i = 1; i < NB_SEGMENTS; i++) {
- assert(!is_private_log_page_in(i, pagenum));
+ /* for (i = 1; i < NB_SEGMENTS; i++) { */
+ /* page_privatize_in(i, pagenum, src); */
+ /* } */
+ /* set_page_private_in(0, pagenum); */
- page_privatize_in(i, pagenum, src);
- }
- set_page_private_in(0, pagenum);
-
- OPT_ASSERT(is_private_log_page_in(my_segnum, pagenum));
- assert(!is_shared_log_page(pagenum));
+ /* OPT_ASSERT(is_private_log_page_in(my_segnum, pagenum)); */
+ /* assert(!is_shared_log_page(pagenum)); */
}
void _stm_write_slowpath(object_t *obj)
@@ -259,23 +257,23 @@
uintptr_t page;
for (page = first_page; page <= end_page; page++) {
- if (is_shared_log_page(page)) {
- long i;
- for (i = 0; i < NB_SEGMENTS; i++) {
- acquire_privatization_lock(i);
- }
- if (is_shared_log_page(page))
- _privatize_shared_page(page);
- for (i = NB_SEGMENTS-1; i >= 0; i--) {
- release_privatization_lock(i);
- }
- }
+ XXX();
+ /* if (is_shared_log_page(page)) { */
+ /* long i; */
+ /* for (i = 0; i < NB_SEGMENTS; i++) { */
+ /* acquire_privatization_lock(i); */
+ /* } */
+ /* if (is_shared_log_page(page)) */
+ /* _privatize_shared_page(page); */
+ /* for (i = NB_SEGMENTS-1; i >= 0; i--) { */
+ /* release_privatization_lock(i); */
+ /* } */
+ /* } */
}
/* pages not shared anymore. but we still may have
only a read protected page ourselves: */
acquire_privatization_lock(my_segnum);
- OPT_ASSERT(is_private_log_page_in(my_segnum, first_page));
/* remove the WRITE_BARRIER flag */
obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -19,7 +19,8 @@
for (i = 0; i < NB_SEGMENTS; i++) {
acquire_privatization_lock(i);
}
- pages_initialize_shared((pages_addr - stm_object_pages) / 4096UL, num);
+ pages_initialize_shared_for(STM_SEGMENT->segment_num,
+ (pages_addr - stm_object_pages) / 4096UL, num);
for (i = NB_SEGMENTS-1; i >= 0; i--) {
release_privatization_lock(i);
}
diff --git a/c8/stm/pages.c b/c8/stm/pages.c
--- a/c8/stm/pages.c
+++ b/c8/stm/pages.c
@@ -11,12 +11,11 @@
static void teardown_pages(void)
{
- memset(pages_privatized, 0, sizeof(pages_privatized));
+ memset(pages_status, 0, sizeof(pages_status));
}
/************************************************************/
-
-static void d_remap_file_pages(char *addr, size_t size, ssize_t pgoff)
+static void check_remap_makes_sense(char *addr, size_t size, ssize_t pgoff)
{
dprintf(("remap_file_pages: 0x%lx bytes: (seg%ld %p) --> (seg%ld %p)\n",
(long)size,
@@ -35,21 +34,26 @@
/* 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);
+}
+
+static void d_remap_file_pages(char *addr, size_t size, ssize_t pgoff)
+{
+ check_remap_makes_sense(addr, size, pgoff);
char *res = mmap(addr, size,
PROT_READ | PROT_WRITE,
- (MAP_PAGES_FLAGS & ~MAP_ANONYMOUS) | MAP_FIXED,
+ MAP_PRIVATE | MAP_NORESERVE | MAP_FIXED,
stm_object_pages_fd, pgoff * 4096UL);
if (UNLIKELY(res != addr))
stm_fatalerror("mmap (remapping page): %m");
}
-static void pages_initialize_shared(uintptr_t pagenum, uintptr_t count)
+static void pages_initialize_shared_for(long segnum, uintptr_t pagenum, uintptr_t count)
{
/* 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. */
+ pagenum+count) PAGE_SHARED in segnum, and PAGE_NO_ACCESS in other segments */
+
dprintf(("pages_initialize_shared: 0x%ld - 0x%ld\n", pagenum,
pagenum + count));
#ifndef NDEBUG
@@ -61,62 +65,63 @@
assert(pagenum < NB_PAGES);
if (count == 0)
return;
+
+ /* already shared after setup.c (also for the other count-1 pages) */
+ assert(get_page_status_in(segnum, pagenum) == PAGE_SHARED);
+
+ /* make other segments NO_ACCESS: */
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);
- }
+ for (i = 0; i < NB_SEGMENTS; i++) {
+ if (i != segnum) {
+ char *segment_base = get_segment_base(i);
+ mprotect(segment_base + pagenum * 4096UL,
+ count * 4096UL, PROT_NONE);
+ }
- for (i = 0; i < NB_SEGMENTS; i++) {
- uintptr_t amount = count;
- while (amount-->0) {
- volatile struct page_shared_s *ps2 = (volatile struct page_shared_s *)
- &pages_privatized[pagenum + amount - PAGE_FLAG_START];
-
- ps2->by_segment = 0; /* not private */
- }
+ long amount = count;
+ while (amount-->0)
+ set_page_status_in(i, pagenum + amount, PAGE_NO_ACCESS);
}
}
-static void page_privatize_in(int segnum, uintptr_t pagenum, char *initialize_from)
-{
-#ifndef NDEBUG
- long l;
- for (l = 0; l < NB_SEGMENTS; l++) {
- assert(get_priv_segment(l)->privatization_lock);
- }
-#endif
+/* static void page_privatize_in(int segnum, uintptr_t pagenum, char *initialize_from) */
+/* { */
+/* #ifndef NDEBUG */
+/* long l; */
+/* for (l = 0; l < NB_SEGMENTS; l++) { */
+/* assert(get_priv_segment(l)->privatization_lock); */
+/* } */
+/* #endif */
- /* check this thread's 'pages_privatized' bit */
- uint64_t bitmask = 1UL << segnum;
- volatile struct page_shared_s *ps = (volatile struct page_shared_s *)
- &pages_privatized[pagenum - PAGE_FLAG_START];
- if (ps->by_segment & bitmask) {
- /* the page is already privatized; nothing to do */
- return;
- }
+/* /\* check this thread's 'pages_privatized' bit *\/ */
+/* uint64_t bitmask = 1UL << segnum; */
+/* volatile struct page_shared_s *ps = (volatile struct page_shared_s *) */
+/* &pages_privatized[pagenum - PAGE_FLAG_START]; */
+/* if (ps->by_segment & bitmask) { */
+/* /\* the page is already privatized; nothing to do *\/ */
+/* return; */
+/* } */
- dprintf(("page_privatize(%lu) in seg:%d\n", pagenum, segnum));
+/* dprintf(("page_privatize(%lu) in seg:%d\n", pagenum, segnum)); */
- /* add this thread's 'pages_privatized' bit */
- ps->by_segment |= bitmask;
+/* /\* add this thread's 'pages_privatized' bit *\/ */
+/* ps->by_segment |= bitmask; */
- /* "unmaps" the page to make the address space location correspond
- again to its underlying file offset (XXX later we should again
- attempt to group together many calls to d_remap_file_pages() in
- succession) */
- uintptr_t pagenum_in_file = NB_PAGES * segnum + pagenum;
- char *new_page = stm_object_pages + pagenum_in_file * 4096UL;
+/* /\* "unmaps" the page to make the address space location correspond */
+/* again to its underlying file offset (XXX later we should again */
+/* attempt to group together many calls to d_remap_file_pages() in */
+/* succession) *\/ */
+/* uintptr_t pagenum_in_file = NB_PAGES * segnum + pagenum; */
+/* char *new_page = stm_object_pages + pagenum_in_file * 4096UL; */
- /* first write to the file page directly: */
- ssize_t written = pwrite(stm_object_pages_fd, initialize_from, 4096UL,
- pagenum_in_file * 4096UL);
- if (written != 4096)
- stm_fatalerror("pwrite didn't write the whole page: %zd", written);
+/* /\* first write to the file page directly: *\/ */
+/* ssize_t written = pwrite(stm_object_pages_fd, initialize_from, 4096UL, */
+/* pagenum_in_file * 4096UL); */
+/* if (written != 4096) */
+/* stm_fatalerror("pwrite didn't write the whole page: %zd", written); */
- /* now remap virtual page in segment to the new file page */
- write_fence();
- d_remap_file_pages(new_page, 4096, pagenum_in_file);
-}
+/* /\* now remap virtual page in segment to the new file page *\/ */
+/* write_fence(); */
+/* d_remap_file_pages(new_page, 4096, pagenum_in_file); */
+/* } */
diff --git a/c8/stm/pages.h b/c8/stm/pages.h
--- a/c8/stm/pages.h
+++ b/c8/stm/pages.h
@@ -20,51 +20,61 @@
#define PAGE_FLAG_START END_NURSERY_PAGE
#define PAGE_FLAG_END NB_PAGES
+/* == NB_SHARED_PAGES */
struct page_shared_s {
-#if NB_SEGMENTS <= 8
+#if NB_SEGMENTS <= 4
uint8_t by_segment;
+#elif NB_SEGMENTS <= 8
+ uint16_t by_segment;
#elif NB_SEGMENTS <= 16
- uint16_t by_segment;
+ uint32_t by_segment;
#elif NB_SEGMENTS <= 32
- uint32_t by_segment;
-#elif NB_SEGMENTS <= 64
uint64_t by_segment;
#else
-# error "NB_SEGMENTS > 64 not supported right now"
+# error "NB_SEGMENTS > 32 not supported right now"
#endif
};
-static struct page_shared_s pages_privatized[PAGE_FLAG_END - PAGE_FLAG_START];
+enum {
+ PAGE_SHARED = 0,
+ PAGE_PRIVATE,
+ PAGE_NO_ACCESS,
+};
-static void pages_initialize_shared(uintptr_t pagenum, uintptr_t count);
-static void page_privatize_in(int segnum, uintptr_t pagenum, char *initialize_from);
+static struct page_shared_s pages_status[NB_SHARED_PAGES];
+
+static void pages_initialize_shared_for(long segnum, uintptr_t pagenum, uintptr_t count);
+/* static void page_privatize_in(int segnum, uintptr_t pagenum, char *initialize_from); */
+
+
+static inline uint8_t get_page_status_in(long segnum, uintptr_t pagenum)
+{
+ int seg_shift = segnum * 2;
+ uint64_t bitmask = 3UL << seg_shift;
+ volatile struct page_shared_s *ps = (volatile struct page_shared_s *)
+ &pages_status[pagenum - PAGE_FLAG_START];
+
+ return ((ps->by_segment & bitmask) >> seg_shift) & 3;
+}
+
+static inline void set_page_status_in(long segnum, uintptr_t pagenum, uint8_t status)
+{
+ OPT_ASSERT((status & 3) == status);
+
+ int seg_shift = segnum * 2;
+ volatile struct page_shared_s *ps = (volatile struct page_shared_s *)
+ &pages_status[pagenum - PAGE_FLAG_START];
+
+ assert(status != get_page_status_in(segnum, pagenum));
+ ps->by_segment |= status << seg_shift;
+}
+
+
static inline uintptr_t get_virt_page_of(long segnum, uintptr_t pagenum)
{
/* logical page -> virtual page */
return (uintptr_t)get_segment_base(segnum) / 4096UL + pagenum;
}
-
-static inline bool is_shared_log_page(uintptr_t pagenum)
-{
- assert(pagenum >= PAGE_FLAG_START);
- return pages_privatized[pagenum - PAGE_FLAG_START].by_segment == 0;
-}
-
-static inline void set_page_private_in(long segnum, uintptr_t pagenum)
-{
- uint64_t bitmask = 1UL << segnum;
- volatile struct page_shared_s *ps = (volatile struct page_shared_s *)
- &pages_privatized[pagenum - PAGE_FLAG_START];
- assert(!(ps->by_segment & bitmask));
- ps->by_segment |= bitmask;
-}
-
-static inline bool is_private_log_page_in(long segnum, uintptr_t pagenum)
-{
- assert(pagenum >= PAGE_FLAG_START);
- uint64_t bitmask = 1UL << segnum;
- return (pages_privatized[pagenum - PAGE_FLAG_START].by_segment & bitmask);
-}
More information about the pypy-commit
mailing list