]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: size arena to fit in virtual address space limit
authorRuss Cox <rsc@golang.org>
Fri, 24 Feb 2012 20:28:51 +0000 (15:28 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 24 Feb 2012 20:28:51 +0000 (15:28 -0500)
For Brad.
Now FreeBSD/386 binaries run on nearlyfreespeech.net.

Fixes #2302.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5700060

16 files changed:
src/pkg/runtime/malloc.goc
src/pkg/runtime/os_freebsd.h
src/pkg/runtime/os_linux.h
src/pkg/runtime/runtime.h
src/pkg/runtime/sys_freebsd_386.s
src/pkg/runtime/sys_freebsd_amd64.s
src/pkg/runtime/sys_linux_386.s
src/pkg/runtime/sys_linux_amd64.s
src/pkg/runtime/sys_linux_arm.s
src/pkg/runtime/thread_darwin.c
src/pkg/runtime/thread_freebsd.c
src/pkg/runtime/thread_linux.c
src/pkg/runtime/thread_netbsd.c
src/pkg/runtime/thread_openbsd.c
src/pkg/runtime/thread_plan9.c
src/pkg/runtime/thread_windows.c

index 932e3d9ef639fa1a2811ccc206adb1d79678c7d3..af03f8018d2b72ff42b44b054070c3b8a33511cc 100644 (file)
@@ -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");
index 194d96320d0c119ef6685bb1ac44697343b414bb..da1d8de2ebdd15f7cd34a4365ea5fd2cde1450c7 100644 (file)
@@ -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*);
index ab948ddc1763093c8d3cf4143032698b253dc2d8..87daa3bb125733c8905f0439b84c50d864d5a633 100644 (file)
@@ -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*);
index 1f4407a09358d89128a91f38bb1bae4ab39e8b40..3b0f505e72158c4377e6f26ffd39545fbbbbc55b 100644 (file)
@@ -729,3 +729,4 @@ bool        runtime·showframe(Func*);
 
 void   runtime·ifaceE2I(struct InterfaceType*, Eface, Iface*);
 
+uintptr        runtime·memlimit(void);
index 0e03eac35ad39f769bcb0d90350476ce622a641c..aab4444942ebd1b1d31cef0df53a7eea9c70feeb 100644 (file)
@@ -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
index 8021a4248a14e659cad3d7fd8c35dd1219f357d0..3984ef40ea28509efe39a437d58a141260b03564 100644 (file)
@@ -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)
index 32a18ed03dd7f6a8c93b75ddfbf07ff483596838..b4cefc53fd7ac895a9eda611db68890b4496b8ec 100644 (file)
@@ -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
index 84972b4533413e5dae8f9b75dd10957e00fa7b88..0de5b2aa41cae90760434b01fd277cfc3254d0a4 100644 (file)
@@ -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
index 26101d7123be48421cb9f972a29bee6b8a93cb1c..439df3afa8063c8340164f8e5a75667f39dcfd6a 100644 (file)
@@ -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
index 42fb7702e8f0b771283d42385a8ac86754f9e97f..d170dfb3d33f0fd48bf253a7b75d29e84fa55aa0 100644 (file)
@@ -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;
+}
index 04de03711d06c1039db40c4f4ae135e89493aeba..7871827a97afb276c42c9bd5687ed827753d7a5a 100644 (file)
@@ -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;
+}
index 005fb1df6a4340e038452ddbdb2a021db91f8511..d406a71240c537aa96429284960824783d24a56a 100644 (file)
@@ -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;
+}
index cba7adecf5b72745f020cfa0f099b941cbee4837..7d14e5c68bb93803090e35ffd11749b02ae0660e 100644 (file)
@@ -201,3 +201,9 @@ runtime·sigpanic(void)
        }
        runtime·panicstring(runtime·sigtab[g->sig].name);
 }
+
+uintptr
+runtime·memlimit(void)
+{
+       return 0;
+}
index efe03e3711b0b86b18220097d268e815bf5431d1..704d95a3c6b5a5013706d40c414ded31e1efc1fe 100644 (file)
@@ -201,3 +201,9 @@ runtime·sigpanic(void)
        }
        runtime·panicstring(runtime·sigtab[g->sig].name);
 }
+
+uintptr
+runtime·memlimit(void)
+{
+       return 0;
+}
index 1180fc880a486b0efbe4e0daf82e3d5ebe97f703..7d5c38fc9aaf1fce6b28272485db03324b66eb95 100644 (file)
@@ -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;
+}
index fb3f39db33c3a1d1537d17fc71623af4074a59d1..8feac9711d170d571ef41e453f65c5cfac302fc1 100644 (file)
@@ -425,3 +425,9 @@ os·sigpipe(void)
 {
        runtime·throw("too many writes on closed pipe");
 }
+
+uintptr
+runtime·memlimit(void)
+{
+       return 0;
+}