[pypy-commit] stmgc c8-private-pages: switch back to using an extra segment (seg0) for malloc-things and later for optimizing memory usage
Raemi
noreply at buildbot.pypy.org
Tue Jan 13 11:33:53 CET 2015
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-private-pages
Changeset: r1520:f78d4b6f968e
Date: 2015-01-13 10:43 +0100
http://bitbucket.org/pypy/stmgc/changeset/f78d4b6f968e/
Log: switch back to using an extra segment (seg0) for malloc-things and
later for optimizing memory usage
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -132,7 +132,7 @@
/* find who has the most recent revision of our page */
int copy_from_segnum = -1;
uint64_t most_recent_rev = 0;
- for (i = 0; i < NB_SEGMENTS; i++) {
+ for (i = 1; i < NB_SEGMENTS; i++) {
if (i == my_segnum)
continue;
@@ -350,7 +350,7 @@
/* XXX: this optimization fails in test_basic.py, bug3 */
/* OPT_ASSERT(segment_really_copied_from < (1 << NB_SEGMENTS)); */
/* int segnum; */
- /* for (segnum = 0; segnum < NB_SEGMENTS; segnum++) { */
+ /* for (segnum = 1; segnum < NB_SEGMENTS; segnum++) { */
/* if (segment_really_copied_from & (1UL << segnum)) { */
/* /\* here we can actually have our own modified version, so */
/* make sure to only copy things that are not modified in our */
@@ -1030,6 +1030,7 @@
ssize_t frag_size = STM_PSEGMENT->sq_fragsizes[j];
char *src = REAL_ADDRESS(STM_SEGMENT->segment_base, frag);
+ /* XXX: including the sharing segment? */
for (i = 0; i < NB_SEGMENTS; i++) {
if (i == myself)
continue;
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -17,7 +17,7 @@
#define NB_PAGES (2500*256) // 2500MB
-#define NB_SEGMENTS STM_NB_SEGMENTS
+#define NB_SEGMENTS (STM_NB_SEGMENTS+1) /* +1 for sharing seg 0 */
#define NB_SEGMENTS_MAX 240 /* don't increase NB_SEGMENTS past this */
#define NB_NURSERY_PAGES (STM_GC_NURSERY/4)
@@ -215,7 +215,7 @@
{
#ifndef NDEBUG
long l;
- for (l = 0; l < NB_SEGMENTS; l++) {
+ for (l = 1; l < NB_SEGMENTS; l++) {
if (!get_priv_segment(l)->privatization_lock)
return false;
}
@@ -228,7 +228,7 @@
static inline void acquire_all_privatization_locks()
{
long l;
- for (l = 0; l < NB_SEGMENTS; l++) {
+ for (l = 1; l < NB_SEGMENTS; l++) {
acquire_privatization_lock(l);
}
}
@@ -236,7 +236,7 @@
static inline void release_all_privatization_locks()
{
long l;
- for (l = NB_SEGMENTS-1; l >= 0; l--) {
+ for (l = NB_SEGMENTS-1; l >= 1; l--) {
release_privatization_lock(l);
}
}
@@ -268,7 +268,7 @@
/* acquire locks in global order */
int i;
- for (i = 0; i < NB_SEGMENTS; i++) {
+ for (i = 1; i < NB_SEGMENTS; i++) {
if ((seg_set & (1 << i)) == 0)
continue;
@@ -282,7 +282,7 @@
OPT_ASSERT(seg_set < (1 << NB_SEGMENTS));
int i;
- for (i = 0; i < NB_SEGMENTS; i++) {
+ for (i = 1; i < NB_SEGMENTS; i++) {
if ((seg_set & (1 << i)) == 0)
continue;
diff --git a/c8/stm/fprintcolor.c b/c8/stm/fprintcolor.c
--- a/c8/stm/fprintcolor.c
+++ b/c8/stm/fprintcolor.c
@@ -8,7 +8,8 @@
char buffer[2048];
va_list ap;
int result;
- int size = (int)sprintf(buffer, "\033[%dm[%d,%lx] ", dprintfcolor(),
+ int size = (int)sprintf(buffer, "\033[%dm[%d,%d,%lx] ",
+ dprintfcolor(), STM_SEGMENT->segment_num,
(int)getpid(), (long)pthread_self());
assert(size >= 0);
diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -16,10 +16,7 @@
static void setup_N_pages(char *pages_addr, uint64_t num)
{
/* initialize to |N|P|N|N| */
- long i;
- for (i = 0; i < NB_SEGMENTS; i++) {
- acquire_privatization_lock(i);
- }
+ acquire_all_privatization_locks();
uintptr_t p = (pages_addr - stm_object_pages) / 4096UL;
dprintf(("setup_N_pages(%p, %lu): pagenum %lu\n", pages_addr, num, p));
@@ -27,9 +24,7 @@
page_mark_accessible(STM_SEGMENT->segment_num, p + num);
}
- for (i = NB_SEGMENTS-1; i >= 0; i--) {
- release_privatization_lock(i);
- }
+ release_all_privatization_locks();
}
@@ -68,7 +63,8 @@
{
/* only for tests xxx but stm_setup_prebuilt() uses this now too */
stm_char *p = allocate_outside_nursery_large(size_rounded_up);
- memset(stm_object_pages + (uintptr_t)p, 0, size_rounded_up);
+ /* hardcode segment 1 */
+ memset(get_virtual_address(STM_SEGMENT->segment_num, (object_t *)p), 0, size_rounded_up);
object_t *o = (object_t *)p;
o->stm_flags = GCFLAG_WRITE_BARRIER;
diff --git a/c8/stm/misc.c b/c8/stm/misc.c
--- a/c8/stm/misc.c
+++ b/c8/stm/misc.c
@@ -15,7 +15,7 @@
char *_stm_get_segment_base(long index)
{
- return get_segment_base(index);
+ return get_segment_base(index+1);
}
struct stm_priv_segment_info_s *_stm_segment(void)
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -18,8 +18,10 @@
assert(_STM_FAST_ALLOC <= NURSERY_SIZE);
_stm_nursery_start = NURSERY_START;
- long i;
- for (i = 0; i < NB_SEGMENTS; i++) {
+ long i = 0;
+ get_segment(i)->nursery_current = (stm_char *)-1;
+ get_segment(i)->nursery_end = -1;
+ for (i = 1; i < NB_SEGMENTS; i++) {
get_segment(i)->nursery_current = (stm_char *)NURSERY_START;
get_segment(i)->nursery_end = NURSERY_END;
}
@@ -91,14 +93,13 @@
realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
size = stmcb_size_rounded_up((struct object_s *)realobj);
- if (true /*size > GC_LAST_SMALL_SIZE*/) {
+ if (true || size > GC_LAST_SMALL_SIZE) {
/* case 1: object is not small enough.
Ask gcpage.c for an allocation via largemalloc. */
nobj = (object_t *)allocate_outside_nursery_large(size);
}
else {
/* case "small enough" */
- abort();
nobj = (object_t *)allocate_outside_nursery_small(size);
}
diff --git a/c8/stm/pages.h b/c8/stm/pages.h
--- a/c8/stm/pages.h
+++ b/c8/stm/pages.h
@@ -50,6 +50,11 @@
return get_segment_base(segnum) + pagenum * 4096;
}
+static inline char *get_virtual_address(long segnum, object_t *obj)
+{
+ return get_segment_base(segnum) + (uintptr_t)obj;
+}
+
static inline bool get_page_status_in(long segnum, uintptr_t pagenum)
{
OPT_ASSERT(segnum < 8 * sizeof(struct page_shared_s));
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -74,6 +74,7 @@
setup_signal_handler();
long i;
+ /* including seg0 */
for (i = 0; i < NB_SEGMENTS; i++) {
char *segment_base = get_segment_base(i);
@@ -195,22 +196,21 @@
if (stm_all_thread_locals == NULL) {
stm_all_thread_locals = tl->next = tl->prev = tl;
num = 0;
- }
- else {
+ } else {
tl->next = stm_all_thread_locals;
tl->prev = stm_all_thread_locals->prev;
stm_all_thread_locals->prev->next = tl;
stm_all_thread_locals->prev = tl;
- num = (tl->prev->associated_segment_num + 1) % NB_SEGMENTS;
+ num = (tl->prev->associated_segment_num) % (NB_SEGMENTS-1);
}
/* assign numbers consecutively, but that's for tests; we could also
assign the same number to all of them and they would get their own
numbers automatically. */
- tl->associated_segment_num = num;
+ tl->associated_segment_num = num + 1;
*_get_cpth(tl) = pthread_self();
_init_shadow_stack(tl);
- set_gs_register(get_segment_base(num));
+ set_gs_register(get_segment_base(num + 1));
s_mutex_unlock();
DEBUG_EXPECT_SEGFAULT(true);
diff --git a/c8/stm/smallmalloc.c b/c8/stm/smallmalloc.c
--- a/c8/stm/smallmalloc.c
+++ b/c8/stm/smallmalloc.c
@@ -284,7 +284,7 @@
small_page_lists[szword] = NULL;
/* process the pages that the various segments are busy filling */
- for (i = 0; i < NB_SEGMENTS; i++) {
+ for (i = 1; i < NB_SEGMENTS; i++) {
struct stm_priv_segment_info_s *pseg = get_priv_segment(i);
struct small_free_loc_s **fl =
&pseg->small_malloc_data.loc_free[szword];
diff --git a/c8/stm/sync.c b/c8/stm/sync.c
--- a/c8/stm/sync.c
+++ b/c8/stm/sync.c
@@ -13,7 +13,7 @@
pthread_mutex_t global_mutex;
pthread_cond_t cond[_C_TOTAL];
/* some additional pieces of global state follow */
- uint8_t in_use1[NB_SEGMENTS]; /* 1 if running a pthread */
+ uint8_t in_use1[NB_SEGMENTS]; /* 1 if running a pthread, idx=0 unused */
};
char reserved[192];
} sync_ctl __attribute__((aligned(64)));
@@ -110,28 +110,29 @@
assert(_has_mutex());
assert(_is_tl_registered(tl));
- int num = tl->associated_segment_num;
- if (sync_ctl.in_use1[num] == 0) {
+ int num = tl->associated_segment_num - 1; // 0..NB_SEG-1
+ OPT_ASSERT(num >= 0);
+ if (sync_ctl.in_use1[num+1] == 0) {
/* fast-path: we can get the same segment number than the one
we had before. The value stored in GS is still valid. */
#ifdef STM_TESTS
/* that can be optimized away, except during tests, because
they use only one thread */
- set_gs_register(get_segment_base(num));
+ set_gs_register(get_segment_base(num+1));
#endif
- dprintf(("acquired same segment: %d\n", num));
+ dprintf(("acquired same segment: %d\n", num+1));
goto got_num;
}
/* Look for the next free segment. If there is none, wait for
the condition variable. */
int retries;
- for (retries = 0; retries < NB_SEGMENTS; retries++) {
- num = num % NB_SEGMENTS;
- if (sync_ctl.in_use1[num] == 0) {
+ for (retries = 0; retries < NB_SEGMENTS-1; retries++) {
+ num = (num+1) % (NB_SEGMENTS-1);
+ if (sync_ctl.in_use1[num+1] == 0) {
/* we're getting 'num', a different number. */
- dprintf(("acquired different segment: %d->%d\n", tl->associated_segment_num, num));
- tl->associated_segment_num = num;
- set_gs_register(get_segment_base(num));
+ dprintf(("acquired different segment: %d->%d\n", tl->associated_segment_num, num+1));
+ tl->associated_segment_num = num+1;
+ set_gs_register(get_segment_base(num+1));
goto got_num;
}
}
@@ -142,8 +143,9 @@
/* Return false to the caller, which will call us again */
return false;
got_num:
- sync_ctl.in_use1[num] = 1;
- assert(STM_SEGMENT->segment_num == num);
+ OPT_ASSERT(num >= 0 && num < NB_SEGMENTS-1);
+ sync_ctl.in_use1[num+1] = 1;
+ assert(STM_SEGMENT->segment_num == num+1);
assert(STM_SEGMENT->running_thread == NULL);
STM_SEGMENT->running_thread = tl;
return true;
@@ -171,7 +173,7 @@
bool _stm_in_transaction(stm_thread_local_t *tl)
{
int num = tl->associated_segment_num;
- assert(0 <= num && num < NB_SEGMENTS);
+ assert(1 <= num && num < NB_SEGMENTS);
return get_segment(num)->running_thread == tl;
}
@@ -184,7 +186,7 @@
void _stm_test_switch_segment(int segnum)
{
- set_gs_register(get_segment_base(segnum));
+ set_gs_register(get_segment_base(segnum+1));
}
#if STM_TESTS
@@ -219,7 +221,7 @@
assert(_has_mutex());
long i;
- for (i = 0; i < NB_SEGMENTS; i++) {
+ for (i = 1; i < NB_SEGMENTS; i++) {
if (get_segment(i)->nursery_end == NURSERY_END)
get_segment(i)->nursery_end = NSE_SIGPAUSE;
}
@@ -235,7 +237,7 @@
long result = 0;
int my_num = STM_SEGMENT->segment_num;
- for (i = 0; i < NB_SEGMENTS; i++) {
+ for (i = 1; i < NB_SEGMENTS; i++) {
if (i != my_num && get_priv_segment(i)->safe_point == SP_RUNNING) {
assert(get_segment(i)->nursery_end <= _STM_NSE_SIGNAL_MAX);
result++;
@@ -252,7 +254,7 @@
assert((_safe_points_requested = false, 1));
long i;
- for (i = 0; i < NB_SEGMENTS; i++) {
+ for (i = 1; i < NB_SEGMENTS; i++) {
assert(get_segment(i)->nursery_end != NURSERY_END);
if (get_segment(i)->nursery_end == NSE_SIGPAUSE)
get_segment(i)->nursery_end = NURSERY_END;
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -1,4 +1,3 @@
-import os
import cffi, weakref
from common import parent_dir, source_files
More information about the pypy-commit
mailing list