[fiber] Moving fibers between threads
Dear Boost, At work I need to move a Boost Fiber from one kernel thread to another. There is a dedicated documentation page for this: https://www.boost.org/doc/libs/1_83_0/libs/fiber/doc/html/fiber/migration.ht... What that page doesn't say is how to migrate yourself if you're currently within a Fiber to another kernel thread, as the docs only talk about migrating Fibers currently not executing and in the ready not sleeping state. I guess this would work: 1. Create a new Fiber, and go into a loop giving up the current execution. 2. When that new Fiber executes, migrate the original fiber to its new kernel thread, then have it exit the loop so it proceeds. Then self immolate, as you're done. But now you're creating and destroying a whole Fiber just to migrate a Fiber between kernel threads, and that feels icky. I don't suppose there's a better way e.g. some sort of way of asking the current thread's Fiber scheduler to call a function when it's next not executing a Fiber? That would avoid the needless Fiber creation and destruction per migration of a Fiber across kernel threads. Thanks for help in advance. Niall
Yoi can't move a runnong fiber to anotjer thread. A fiber is simply a stack (+ some registers) that is assigned a thread for execution.
27.09.2023 22:12:57 Niall Douglas via Boost
Dear Boost,
At work I need to move a Boost Fiber from one kernel thread to another. There is a dedicated documentation page for this:
https://www.boost.org/doc/libs/1_83_0/libs/fiber/doc/html/fiber/migration.ht...
What that page doesn't say is how to migrate yourself if you're currently within a Fiber to another kernel thread, as the docs only talk about migrating Fibers currently not executing and in the ready not sleeping state. I guess this would work:
1. Create a new Fiber, and go into a loop giving up the current execution.
2. When that new Fiber executes, migrate the original fiber to its new kernel thread, then have it exit the loop so it proceeds. Then self immolate, as you're done.
But now you're creating and destroying a whole Fiber just to migrate a Fiber between kernel threads, and that feels icky.
I don't suppose there's a better way e.g. some sort of way of asking the current thread's Fiber scheduler to call a function when it's next not executing a Fiber? That would avoid the needless Fiber creation and destruction per migration of a Fiber across kernel threads.
Thanks for help in advance.
Niall
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 28/09/2023 05:09, oliver.kowalke@gmail.com wrote:
Yoi can't move a runnong fiber to anotjer thread. A fiber is simply a stack (+ some registers) that is assigned a thread for execution.
Boost.Fiber's own work stealing scheduler moves fibers between threads. They can't be running at the time for obvious reasons, they get their context suspended, then you detach() the suspended context on the source thread, then it gets attach() on the destination thread, then execution is resumed. Apart from GDB showing worryingly incorrect stacktraces after thread migration for the stack preceding fiber creation, this works fine. I'm currently using a condvar's wait_queue to do the suspension and resumption, and a helper fiber to do the context detach and reattach across kernel threads. Which brings me back to my original question:
But now you're creating and destroying a whole Fiber just to migrate a Fiber between kernel threads, and that feels icky.
I don't suppose there's a better way e.g. some sort of way of asking the current thread's Fiber scheduler to call a function when it's next not executing a Fiber? That would avoid the needless Fiber creation and destruction per migration of a Fiber across kernel threads.
I can create a custom scheduler and that solves the problem without issue without any inefficiency. But that's effort. I can use a thread local stack of items to pop off and execute next time the fiber scheduler exits back to normal code per kernel thread, but that's effort and requires a whole bunch of malloc and it's intrusive. I can create a helper fiber to do the thread migration for me, but that wastes a fiber per kernel thread. I guess what I'm wondering is how come boost::fibers::wait_queue isn't documented, and why can't I have lightweight context which doesn't contain any actual stack nor other gubbins, and just calls some callable per scheduler invocation? I appreciate Boost.Fiber is very mature nowadays, so I'm not asking for new features or a substantial refactoring. I guess I really just want a maximally efficient way of manually moving a Fiber across kernel threads just like I can with a suspended C++ coroutine, and I don't currently see one in Boost.Fiber? Niall
sorry - I don't get it... A fiber is a stack and is used to store the preserved registeres - a simple push if fiber gets suspended so that only a pointer to the end of the stack holds all the required data (sztack itself + preserved registers).
participants (3)
-
Niall Douglas
-
Oliver Kowalke
-
oliver.kowalke@gmail.com