diff options
| author | Russ Cox <rsc@golang.org> | 2012-02-24 15:28:51 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2012-02-24 15:28:51 -0500 |
| commit | 102274a30e5d2df4d13d5fad50c484f78904236a (patch) | |
| tree | 20384f9d94d1d7c9e934014c7d219c5be07c4aed /src | |
| parent | d8ccebfffa40b016d9e90713ce0430c37d98175c (diff) | |
| download | go-102274a30e5d2df4d13d5fad50c484f78904236a.tar.xz | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/pkg/runtime/malloc.goc | 11 | ||||
| -rw-r--r-- | src/pkg/runtime/os_freebsd.h | 8 | ||||
| -rw-r--r-- | src/pkg/runtime/os_linux.h | 8 | ||||
| -rw-r--r-- | src/pkg/runtime/runtime.h | 1 | ||||
| -rw-r--r-- | src/pkg/runtime/sys_freebsd_386.s | 5 | ||||
| -rw-r--r-- | src/pkg/runtime/sys_freebsd_amd64.s | 7 | ||||
| -rw-r--r-- | src/pkg/runtime/sys_linux_386.s | 7 | ||||
| -rw-r--r-- | src/pkg/runtime/sys_linux_amd64.s | 7 | ||||
| -rw-r--r-- | src/pkg/runtime/sys_linux_arm.s | 8 | ||||
| -rw-r--r-- | src/pkg/runtime/thread_darwin.c | 10 | ||||
| -rw-r--r-- | src/pkg/runtime/thread_freebsd.c | 28 | ||||
| -rw-r--r-- | src/pkg/runtime/thread_linux.c | 28 | ||||
| -rw-r--r-- | src/pkg/runtime/thread_netbsd.c | 6 | ||||
| -rw-r--r-- | src/pkg/runtime/thread_openbsd.c | 6 | ||||
| -rw-r--r-- | src/pkg/runtime/thread_plan9.c | 6 | ||||
| -rw-r--r-- | src/pkg/runtime/thread_windows.c | 6 |
16 files changed, 151 insertions, 1 deletions
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<<PageShift) - 1); + arena_size = bitmap_size * 8; + } // SysReserve treats the address we ask for, end, as a hint, // not as an absolute requirement. If we ask for the end @@ -340,6 +347,8 @@ runtime·mallocinit(void) p = runtime·SysReserve(want, bitmap_size + arena_size); if(p == nil) runtime·throw("runtime: cannot reserve arena virtual address space"); + if((uintptr)p & (((uintptr)1<<PageShift)-1)) + runtime·printf("runtime: SysReserve returned unaligned address %p; asked for %p", p, bitmap_size+arena_size); } if((uintptr)p & (((uintptr)1<<PageShift)-1)) runtime·throw("runtime: SysReserve returned unaligned address"); diff --git a/src/pkg/runtime/os_freebsd.h b/src/pkg/runtime/os_freebsd.h index 194d96320d..da1d8de2eb 100644 --- a/src/pkg/runtime/os_freebsd.h +++ b/src/pkg/runtime/os_freebsd.h @@ -17,3 +17,11 @@ void runtime·raisesigpipe(void); #define NSIG 33 #define SI_USER 0 + +#define RLIMIT_AS 10 +typedef struct Rlimit Rlimit; +struct Rlimit { + int64 rlim_cur; + int64 rlim_max; +}; +int32 runtime·getrlimit(int32, Rlimit*); diff --git a/src/pkg/runtime/os_linux.h b/src/pkg/runtime/os_linux.h index ab948ddc17..87daa3bb12 100644 --- a/src/pkg/runtime/os_linux.h +++ b/src/pkg/runtime/os_linux.h @@ -33,3 +33,11 @@ struct Sigset }; void runtime·rtsigprocmask(int32, Sigset*, Sigset*, int32); #define SIG_SETMASK 2 + +#define RLIMIT_AS 9 +typedef struct Rlimit Rlimit; +struct Rlimit { + uintptr rlim_cur; + uintptr rlim_max; +}; +int32 runtime·getrlimit(int32, Rlimit*); diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 1f4407a093..3b0f505e72 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -729,3 +729,4 @@ bool runtime·showframe(Func*); void runtime·ifaceE2I(struct InterfaceType*, Eface, Iface*); +uintptr runtime·memlimit(void); diff --git a/src/pkg/runtime/sys_freebsd_386.s b/src/pkg/runtime/sys_freebsd_386.s index 0e03eac35a..aab4444942 100644 --- a/src/pkg/runtime/sys_freebsd_386.s +++ b/src/pkg/runtime/sys_freebsd_386.s @@ -60,6 +60,11 @@ TEXT runtime·write(SB),7,$-4 INT $0x80 RET +TEXT runtime·getrlimit(SB),7,$-4 + MOVL $194, AX + INT $0x80 + RET + TEXT runtime·raisesigpipe(SB),7,$12 // thr_self(&8(SP)) LEAL 8(SP), AX diff --git a/src/pkg/runtime/sys_freebsd_amd64.s b/src/pkg/runtime/sys_freebsd_amd64.s index 8021a4248a..3984ef40ea 100644 --- a/src/pkg/runtime/sys_freebsd_amd64.s +++ b/src/pkg/runtime/sys_freebsd_amd64.s @@ -65,6 +65,13 @@ TEXT runtime·write(SB),7,$-8 SYSCALL RET +TEXT runtime·getrlimit(SB),7,$-8 + MOVL 8(SP), DI + MOVQ 16(SP), SI + MOVL $194, AX + SYSCALL + RET + TEXT runtime·raisesigpipe(SB),7,$16 // thr_self(&8(SP)) LEAQ 8(SP), DI // arg 1 &8(SP) diff --git a/src/pkg/runtime/sys_linux_386.s b/src/pkg/runtime/sys_linux_386.s index 32a18ed03d..b4cefc53fd 100644 --- a/src/pkg/runtime/sys_linux_386.s +++ b/src/pkg/runtime/sys_linux_386.s @@ -52,6 +52,13 @@ TEXT runtime·read(SB),7,$0 CALL *runtime·_vdso(SB) RET +TEXT runtime·getrlimit(SB),7,$0 + MOVL $191, AX // syscall - ugetrlimit + MOVL 4(SP), BX + MOVL 8(SP), CX + CALL *runtime·_vdso(SB) + RET + TEXT runtime·usleep(SB),7,$8 MOVL $0, DX MOVL usec+0(FP), AX diff --git a/src/pkg/runtime/sys_linux_amd64.s b/src/pkg/runtime/sys_linux_amd64.s index 84972b4533..0de5b2aa41 100644 --- a/src/pkg/runtime/sys_linux_amd64.s +++ b/src/pkg/runtime/sys_linux_amd64.s @@ -50,6 +50,13 @@ TEXT runtime·read(SB),7,$0-24 SYSCALL RET +TEXT runtime·getrlimit(SB),7,$0-24 + MOVL 8(SP), DI + MOVQ 16(SP), SI + MOVL $97, AX // syscall entry + SYSCALL + RET + TEXT runtime·usleep(SB),7,$16 MOVL $0, DX MOVL usec+0(FP), AX diff --git a/src/pkg/runtime/sys_linux_arm.s b/src/pkg/runtime/sys_linux_arm.s index 26101d7123..439df3afa8 100644 --- a/src/pkg/runtime/sys_linux_arm.s +++ b/src/pkg/runtime/sys_linux_arm.s @@ -33,6 +33,7 @@ #define SYS_tkill (SYS_BASE + 238) #define SYS_sched_yield (SYS_BASE + 158) #define SYS_select (SYS_BASE + 142) // newselect +#define SYS_ugetrlimit (SYS_BASE + 191) #define ARM_BASE (SYS_BASE + 0x0f0000) #define SYS_ARM_cacheflush (ARM_BASE + 2) @@ -72,6 +73,13 @@ TEXT runtime·read(SB),7,$0 SWI $0 RET +TEXT runtime·getrlimit(SB),7,$0 + MOVW 0(FP), R0 + MOVW 4(FP), R1 + MOVW $SYS_ugetrlimit, R7 + SWI $0 + RET + TEXT runtime·exit(SB),7,$-4 MOVW 0(FP), R0 MOVW $SYS_exit_group, R7 diff --git a/src/pkg/runtime/thread_darwin.c b/src/pkg/runtime/thread_darwin.c index 42fb7702e8..d170dfb3d3 100644 --- a/src/pkg/runtime/thread_darwin.c +++ b/src/pkg/runtime/thread_darwin.c @@ -424,3 +424,13 @@ void runtime·osyield(void) { } + +uintptr +runtime·memlimit(void) +{ + // NOTE(rsc): Could use getrlimit here, + // like on FreeBSD or Linux, but Darwin doesn't enforce + // ulimit -v, so it's unclear why we'd try to stay within + // the limit. + return 0; +} diff --git a/src/pkg/runtime/thread_freebsd.c b/src/pkg/runtime/thread_freebsd.c index 04de03711d..7871827a97 100644 --- a/src/pkg/runtime/thread_freebsd.c +++ b/src/pkg/runtime/thread_freebsd.c @@ -161,3 +161,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_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; +} |
