runtime: If no split stacks, allocate stacks using mmap on 64-bit systems.
authorIan Lance Taylor <ian@gcc.gnu.org>
Sat, 31 Oct 2015 23:48:19 +0000 (23:48 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sat, 31 Oct 2015 23:48:19 +0000 (23:48 +0000)
    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

gcc/go/gofrontend/MERGE
libgo/runtime/proc.c

index 8eae1f4c9e7a422bbdf3c488533986d821d90ec5..d2c9492b54d41c2dafe8eb31a86a9a00da266476 100644 (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.
index b5741c54cc9008413e24766aae3a257135c35f09..c25a21731abf00f9c2c93b8b4548837bde3e9508 100644 (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;