System-Managed Stack Attributes
Win32 provides somewhat limited control over the stack allocation process. Unless otherwise indicated, the default stack attributes for a newly created thread are inherited from the creating thread. Both the amount of virtual address space to reserve, and the amount of physical memory to commit are inherited. Win32 provides no method for interrogating these values.
The stack size for the initial thread in a process is defined by the default stack attributes of that process. The default stack attributes for a process are 1MB reserved and one page (4KB) committed unless specified otherwise using a linker switch or .DEF file entry.
Following allocation, the operating system will grow the stack as needed by committing one-page blocks (4K on an x86 machine) out of the reserved stack memory. Once all of the reserved memory has been committed, the system will attempt to continue to grow the stack into the memory adjacent to the memory reserved for the stack.
Once the stack grows to the point where there is no free memory adjacent to the stack (and this may happen as soon as the initial reserve has been committed), the stack cannot grow any farther. At this point, further stack growth will produce exceptions, error, or other unpredictable behavior. To avoid this situation, you should take care to specify a sufficient amount of reserved memory space for your stacks when you link your program.
Each new thread gets its own stack space of committed and reserved memory. The Win32 API allows a new commit size to be specified when creating a thread. If a new size is not specified, the new thread takes on the same stack size and commit size as the thread that created it, whether that be the default values, the values defined in the DEF file, or values defined with a linker switch. If the commit size specified is larger than the default process stack size, the new thread is given a stack allocation equal to the commit size.
Win32 automatically commits more memory from the reserved stack space as needed, but cannot commit more than the total amount initially reserved. Remember that the only resource consumed by reserving space is addresses in the virtual address space of your process; no memory or pagefile space is allocated until the memory is committed. Therefore, there is little harm in reserving a large area if it might be needed.
To summarize, the reserve size and default commit size of the stack is established at link-time. You may choose to commit a different amount when you create a thread, but you can only increase the reserve size of the stack by committing more memory than is reserved. Win32 provides no method for querying the stack size at run-time, so you will not be able to determine, at run-time, what portion of the reserved space you have mapped into memory when you specify a commit size, nor will you be able to determine when it may be necessary to commit more memory in order to increase the stack size.
Since you have no control over the reserve size of the stack, the
getMinStackSize() function is not supported under Win32, and will produce an
RWTHROperationNotSupported exception if used.
Stack Reserve Size. Even though stack reserve size is defined in the context of the Win32 system, the amount of memory reserve is fixed at link-time and cannot be obtained from the Win32 API. Therefore, the Threads Module does not support this attribute in its Win32 implementation. Attempts to get or set the reserve size attribute will result in exceptions.
Stack Commit Size. The commit size attribute allows you to specify the amount of physical memory or pagefile space to commit to a thread’s stack when that thread is created.
Under Win32, the default value for the commit size attribute is inherited from the creating thread, and cannot be queried unless the querying thread was created with a non-default commit size. The typical default commit size is one page or 4KB of memory, unless otherwise specified by a .DEF file entry or linker switch.
The Threads Module imposes a lower limit of 1 for the minimum commit size, and imposes no limit on the maximum stack size. The maximum stack size is effectively limited by available virtual memory space and pagefile size. If the stack commit size specified is too large for the available resources, an exception will be produced when a thread is created and initialized using the offending thread attribute instance. Any such exception is thrown by the start() function invocation that attempted to create the thread.