runtime: default os stack size on windows amd64 is too small
Closed this issue · 6 comments
bryanturley commented
Yesterday I tested some opengl code on windows amd64 with go1.3rc2 with the newest beta amd opengl driver, and it runs out of os stack space during the initial gl context setup. In pkg/runtime/os_windows.c runtime·newosproc thandle = runtime·stdcall(runtime·CreateThread, 6, nil, (uintptr)0x20000, runtime·tstart_stdcall, mp, STACK_SIZE_PARAM_IS_A_RESERVATION, nil); 0x20000 (128KBytes) reserved stack. Doing some reading the default os stack is 1MB (reserved), which would be in most cases unused so I can agree with a much smaller default size. Doubling the reserved stack fixes the problem. While doing this I noticed that there does not seem to be a difference between what is reserved on 32bit and 64bit. I would assume 64bit would need >= twice what 32bit has. I am guessing the original thread has a larger os stack size, but I have been doing one goroutine per window which feels more "go" that trying to cram everything onto the main thread. It also keeps operations on one window from blocking operations on other windows. Could we get windows amd64's reserved stack size doubled for 1.3 release? Perhaps a new version of runtime.LockOSThread() for go1.4 func LockSizedOSThread(osStackSize int32) Which would create a new os thread with osStackSize stack and lock the calling goroutine onto it?
ianlancetaylor commented
bradfitz commented
1.3 is frozen. If the code worked on 1.2, changing something might be okay for 1.3.1. Please clarify. I doubt we'll give users control of stack size, since Go manages (Go) stacks automatically, growing and shrinking them as needed. It would be a weird API, even in the runtime package. For cgo calls, I'm not sure the best way to control the C stack size. Others might have thoughts.
bryanturley commented
The clearest way to say it would be. C (not go) code on windows amd64 expects much larger os (not go) stacks. If there was a way to increase the os thread's stack size after it is created in windows I would not have filed this bug. Doubling the current stack reservation on windows amd64 fixes my problem, it may not fix other stack hungry c/cgo code. To fix other c stack (not go stack) hungry code I was recommending a function that started a new os thread with a much larger (and user defined) os stack size than the default, and then locking down the goroutine in the same way as a normal runtime.LockOSThread() to that thread. This would keep the amount of reserved memory low for randomly created threads, while enabling the use of stack hungry c code inside of that locked goroutine. Short fix for me is pkg/runtime/os_windows.c runtime·newosproc thandle = runtime·stdcall(runtime·CreateThread, 6, nil, (uintptr)0x20000, runtime·tstart_stdcall, mp, STACK_SIZE_PARAM_IS_A_RESERVATION, nil); Change 0x20000 (128KB) to 0x40000 (256KB) == real problem with a mainstream opengl driver running a necessary and basic initialization operation goes away. This would affect every os thread created, so having a runtime.LockSizedOSThread() would create a way to have small (0x20000) default stacks for normal threads and have troublesome c/cgo code running locked in a thread with a larger os stack.
alexbrainman commented
bryanturley commented
Sorry, I figured it out. Digging deeper this is happening because of https://golang.org/issue/4069 Feel free to close this issue, it is indirectly caused by 4069. I will find a work around till that gets fixed. Also congrats to the go team on go1.3 ;)
davecheney commented