diff mbox

libgo patch committed: When non-split-stack, allocate 64-bit stack using mmap

Message ID CAOyqgcV_jRWGyHz=2FuwQuubjsSVyttdtySLXOGm0EzuFB0nRA@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor Oct. 31, 2015, 11:48 p.m. UTC
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.

Bootstrapped and ran Go tests on x86_64-pc-linux-gnu.  Also did the
same using a version of gccgo patched to not use split stacks.
Committed to mainline.

Ian
diff mbox

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 229624)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -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: libgo/runtime/proc.c
===================================================================
--- libgo/runtime/proc.c	(revision 229616)
+++ libgo/runtime/proc.c	(working copy)
@@ -2250,11 +2250,24 @@  runtime_malg(int32 stacksize, byte** ret
 		__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;