[boost] [fiber] Moving fibers between threads

32 views
Skip to first unread message

Niall Douglas via Boost

unread,
Sep 27, 2023, 4:12:40 PM9/27/23
to Boost Developers List, Niall Douglas
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.html

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

oliver.kowalke--- via Boost

unread,
Sep 28, 2023, 12:10:02 AM9/28/23
to Niall Douglas via Boost, oliver....@gmail.com
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 <bo...@lists.boost.org>:

Niall Douglas via Boost

unread,
Sep 28, 2023, 11:54:08 AM9/28/23
to oliver....@gmail.com, Boost Developers List, Niall Douglas
On 28/09/2023 05:09, oliver....@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?

Oliver Kowalke via Boost

unread,
Sep 28, 2023, 1:30:05 PM9/28/23
to Niall Douglas, Boost Developers List, Oliver Kowalke
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).
Reply all
Reply to author
Forward
0 new messages