SergeyMakeev / TaskScheduler

Cross-platform, fiber-based, multi-threaded task scheduler designed for video games.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The ::CreateFiberEx stack size issue...

ChemistAion opened this issue · comments

commented

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

commented

BTW: I noticed that fiber received after from-thread-conversion through ::ConvertThreadToFiberEx is left alone:

fiber = ::ConvertThreadToFiberEx(nullptr, MW_FIBER_FLAG_FLOAT_SWITCH);

It should be paired (freed) with ::ConvertFiberToThread during e.g.: Fiber::CleanUp.

commented

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 most dwStackReserveSize-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