golang/go

runtime: default os stack size on windows amd64 is too small

Closed this issue · 6 comments

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?

Comment 1:

Labels changed: added repo-main, release-go1.4, os-windows.

Comment 2:

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.

Comment 3:

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.

Comment 4:

bryanturley,
Do you use cgo?
Alex

Comment 5:

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 ;)

Comment 6:

Status changed to Retracted.