The ::CreateFiberEx stack size issue...
ChemistAion opened this issue · comments
To make it work correctly dwStackCommitSize
must be less than dwStackReserveSize
.
I did some research about this and I found these hints: ReactOS BaseCreateStack
ReactOS implementation follows somehow Thread Stack Size:
To change the initially committed stack space, use the dwStackSize parameter (...).This value is rounded up to the nearest page. Generally, the reserve size is the default reserve size specified in the executable header. However, if the initially committed size specified by dwStackSize is larger than or equal to the default reserve size, the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.
To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially committed size is the default size specified in the executable header. For fibers, use the dwStackReserveSize parameter of CreateFiberEx. The committed size is specified in the dwStackCommitSize parameter.
IMO native Windows ::CreateFiberEx
is implemented similary (wrongly) to what ReactOS provides, so, e.g.: ::CreateFiberEx(0, 1<<16, ...);
or ::CreateFiberEx((1<<16)-1, 1<<16, ...);
does the job and gives fiber with one page stack... enjoy :)
BTW: I noticed that fiber received after from-thread-conversion through ::ConvertThreadToFiberEx
is left alone:
It should be paired (freed) with ::ConvertFiberToThread
during e.g.: Fiber::CleanUp
.
Some final thoughts on ::ConvertThreadToFiberEx
usage:
- stack cannot be smaller than
SYSTEM_INFO.dwAllocationGranularity
(default: 4kB), otherwise we will land back to default 1MB; - if we also want to commit the stack during its reservation we need to set
dwStackCommitSize
as/at mostdwStackReserveSize-1
(to pass the test as I pointed in my first comment); - both parameters will be rounded to
SYSTEM_INFO.dwPageSize
no matter what we are doing;
This approach is proven in the field/production, e.g. Ruby is using ::ConvertThreadToFiberEx
in such a way since very first native fibers implementation: Ruby FIBER_USE_NATIVE patch