[pypy-commit] stmgc default: some refactoring
Raemi
noreply at buildbot.pypy.org
Thu Sep 4 17:31:34 CEST 2014
Author: Remi Meier <remi.meier at 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 */
}
}
}
More information about the pypy-commit
mailing list