From 102274a30e5d2df4d13d5fad50c484f78904236a Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 24 Feb 2012 15:28:51 -0500 Subject: [PATCH] runtime: size arena to fit in virtual address space limit For Brad. Now FreeBSD/386 binaries run on nearlyfreespeech.net. Fixes #2302. R=golang-dev, r CC=golang-dev https://golang.org/cl/5700060 --- src/pkg/runtime/malloc.goc | 11 ++++++++++- src/pkg/runtime/os_freebsd.h | 8 ++++++++ src/pkg/runtime/os_linux.h | 8 ++++++++ src/pkg/runtime/runtime.h | 1 + src/pkg/runtime/sys_freebsd_386.s | 5 +++++ src/pkg/runtime/sys_freebsd_amd64.s | 7 +++++++ src/pkg/runtime/sys_linux_386.s | 7 +++++++ src/pkg/runtime/sys_linux_amd64.s | 7 +++++++ src/pkg/runtime/sys_linux_arm.s | 8 ++++++++ src/pkg/runtime/thread_darwin.c | 10 ++++++++++ src/pkg/runtime/thread_freebsd.c | 28 ++++++++++++++++++++++++++++ src/pkg/runtime/thread_linux.c | 28 ++++++++++++++++++++++++++++ src/pkg/runtime/thread_netbsd.c | 6 ++++++ src/pkg/runtime/thread_openbsd.c | 6 ++++++ src/pkg/runtime/thread_plan9.c | 6 ++++++ src/pkg/runtime/thread_windows.c | 6 ++++++ 16 files changed, 151 insertions(+), 1 deletion(-) diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index 932e3d9ef6..af03f8018d 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -262,6 +262,7 @@ runtime·mallocinit(void) uintptr arena_size, bitmap_size; extern byte end[]; byte *want; + uintptr limit; p = nil; arena_size = 0; @@ -274,10 +275,12 @@ runtime·mallocinit(void) runtime·InitSizes(); + limit = runtime·memlimit(); + // Set up the allocation arena, a contiguous area of memory where // allocated data will be found. The arena begins with a bitmap large // enough to hold 4 bits per allocated word. - if(sizeof(void*) == 8) { + if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) { // On a 64-bit machine, allocate from a single contiguous reservation. // 16 GB should be big enough for now. // @@ -326,6 +329,10 @@ runtime·mallocinit(void) // of address space, which is probably too much in a 32-bit world. bitmap_size = MaxArena32 / (sizeof(void*)*8/4); arena_size = 512<<20; + if(limit > 0 && arena_size+bitmap_size > limit) { + bitmap_size = (limit / 9) & ~((1<sig].name); } + +uintptr +runtime·memlimit(void) +{ + Rlimit rl; + extern byte text[], end[]; + uintptr used; + + if(runtime·getrlimit(RLIMIT_AS, &rl) != 0) + return 0; + if(rl.rlim_cur >= 0x7fffffff) + return 0; + + // Estimate our VM footprint excluding the heap. + // Not an exact science: use size of binary plus + // some room for thread stacks. + used = end - text + (64<<20); + if(used >= rl.rlim_cur) + return 0; + + // If there's not at least 16 MB left, we're probably + // not going to be able to do much. Treat as no limit. + rl.rlim_cur -= used; + if(rl.rlim_cur < (16<<20)) + return 0; + + return rl.rlim_cur - used; +} diff --git a/src/pkg/runtime/thread_linux.c b/src/pkg/runtime/thread_linux.c index 005fb1df6a..d406a71240 100644 --- a/src/pkg/runtime/thread_linux.c +++ b/src/pkg/runtime/thread_linux.c @@ -221,3 +221,31 @@ runtime·sigpanic(void) } runtime·panicstring(runtime·sigtab[g->sig].name); } + +uintptr +runtime·memlimit(void) +{ + Rlimit rl; + extern byte text[], end[]; + uintptr used; + + if(runtime·getrlimit(RLIMIT_AS, &rl) != 0) + return 0; + if(rl.rlim_cur >= 0x7fffffff) + return 0; + + // Estimate our VM footprint excluding the heap. + // Not an exact science: use size of binary plus + // some room for thread stacks. + used = end - text + (64<<20); + if(used >= rl.rlim_cur) + return 0; + + // If there's not at least 16 MB left, we're probably + // not going to be able to do much. Treat as no limit. + rl.rlim_cur -= used; + if(rl.rlim_cur < (16<<20)) + return 0; + + return rl.rlim_cur - used; +} diff --git a/src/pkg/runtime/thread_netbsd.c b/src/pkg/runtime/thread_netbsd.c index cba7adecf5..7d14e5c68b 100644 --- a/src/pkg/runtime/thread_netbsd.c +++ b/src/pkg/runtime/thread_netbsd.c @@ -201,3 +201,9 @@ runtime·sigpanic(void) } runtime·panicstring(runtime·sigtab[g->sig].name); } + +uintptr +runtime·memlimit(void) +{ + return 0; +} diff --git a/src/pkg/runtime/thread_openbsd.c b/src/pkg/runtime/thread_openbsd.c index efe03e3711..704d95a3c6 100644 --- a/src/pkg/runtime/thread_openbsd.c +++ b/src/pkg/runtime/thread_openbsd.c @@ -201,3 +201,9 @@ runtime·sigpanic(void) } runtime·panicstring(runtime·sigtab[g->sig].name); } + +uintptr +runtime·memlimit(void) +{ + return 0; +} diff --git a/src/pkg/runtime/thread_plan9.c b/src/pkg/runtime/thread_plan9.c index 1180fc880a..7d5c38fc9a 100644 --- a/src/pkg/runtime/thread_plan9.c +++ b/src/pkg/runtime/thread_plan9.c @@ -235,3 +235,9 @@ runtime·write(int32 fd, void *buf, int32 nbytes) { return runtime·pwrite(fd, buf, nbytes, -1LL); } + +uintptr +runtime·memlimit(void) +{ + return 0; +} diff --git a/src/pkg/runtime/thread_windows.c b/src/pkg/runtime/thread_windows.c index fb3f39db33..8feac9711d 100644 --- a/src/pkg/runtime/thread_windows.c +++ b/src/pkg/runtime/thread_windows.c @@ -425,3 +425,9 @@ os·sigpipe(void) { runtime·throw("too many writes on closed pipe"); } + +uintptr +runtime·memlimit(void) +{ + return 0; +} -- 2.48.1