runtime: If no split stacks, allocate stacks using mmap on 64-bit systems.

When not using split stacks, libgo allocate large stacks for each
    goroutine.  On a 64-bit system, libgo allocates a maximum of 128G for
    the Go heap, and allocates 4M for each stack.  When the stacks are
    allocated from the Go heap, the result is that a program can only create
    32K goroutines, which is not enough for an active Go server.  This patch
    changes libgo to allocate the stacks using mmap directly, rather than
    allocating them out of the Go heap.  This change is only done for 64-bit
    systems when not using split stacks.  When using split stacks, the
    stacks are allocated using mmap directly anyhow.  On a 32-bit system,
    there is no maximum size for the Go heap, or, rather, the maximum size
    is the available address space anyhow.
    
    Reviewed-on: https://go-review.googlesource.com/16531

From-SVN: r229636
This commit is contained in:
Ian Lance Taylor 2015-10-31 23:48:19 +00:00
parent da235df878
commit 2b193803d7
2 changed files with 16 additions and 3 deletions

View File

@ -1,4 +1,4 @@
17cc10f7fb07e3f37448feaeb416b52618ae8bbb
1c1f226662a6c84eae83f8aaec3d4503e70be843
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -2250,11 +2250,24 @@ runtime_malg(int32 stacksize, byte** ret_stack, size_t* ret_stacksize)
__splitstack_block_signals_context(&newg->stack_context[0],
&dont_block_signals, nil);
#else
*ret_stack = runtime_mallocgc(stacksize, 0, FlagNoProfiling|FlagNoGC);
// In 64-bit mode, the maximum Go allocation space is
// 128G. Our stack size is 4M, which only permits 32K
// goroutines. In order to not limit ourselves,
// allocate the stacks out of separate memory. In
// 32-bit mode, the Go allocation space is all of
// memory anyhow.
if(sizeof(void*) == 8) {
void *p = runtime_SysAlloc(stacksize, &mstats.other_sys);
if(p == nil)
runtime_throw("runtime: cannot allocate memory for goroutine stack");
*ret_stack = (byte*)p;
} else {
*ret_stack = runtime_mallocgc(stacksize, 0, FlagNoProfiling|FlagNoGC);
runtime_xadd(&runtime_stacks_sys, stacksize);
}
*ret_stacksize = stacksize;
newg->gcinitial_sp = *ret_stack;
newg->gcstack_size = stacksize;
runtime_xadd(&runtime_stacks_sys, stacksize);
#endif
}
return newg;