2

Can a fiber created in thread A switch to another fiber created in thread B? To make the question more specific, some operating systems have fibers natively implemented (windows fibers),
other need to implement it themselves (using setjump longjump in linux etc.).

Libcoro for example wraps this all up in a single API (for windows it’s just a wrapper for native fibers, for Linux it implements it itself etc.)

So, if it's possible to migrate fibers between threads, can you give me an example usage in windows (linux) in c/c++?

I found something about fiber migration in the boost library documentation, but it's not specific enough about it's implementation and platform dependence. I still want to understand how to do it myself using only windows fibers for example (or using Libcoro on linux).

If it's not possible in a general way, why so?

I understand that fibers are meant to be used as lightweight threads for cooperative multitasking over a single thread, they have cheap context switching compared to regular threads, and they simplify the programming. An example usage is a system with several threads, each having several fibers doing some kind of work hierarchy on their parent thread (never leaving the parent thread).

Even though it's not the intended use I still want to learn how to do it if it's possible in a general way, because I think I can optimize the work load on my job system by migrating fibers between threads.

DontCareBear
  • 825
  • 2
  • 11
  • 25
  • 3
    At least for Windows fibers, the answer is "yes". From [the documentation on `SwitchToFiber`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms686350.aspx): "You can call `SwitchToFiber` with the address of a fiber created by a different thread." – Igor Tandetnik Jul 11 '17 at 01:20
  • 1
    I don't think there can be a generic answer as "fiber" is a loosely defined term. Fundamentally a fiber captures execution state from a thread. The question therefore is whether it captures the full state. – MSalters Jul 11 '17 at 08:47

1 Answers1

2

The mentioned boost.fiber uses boost.context (callcc/continuation) to implement context switching. Till boost-1.64 callcc was implemented in assembler only, boost-1.65 enables you to choose between assembler, Windows Fibers (Windows) or ucontext (POSIX if available; deprecated API by POSIX). The assembler implementation is faster that the other two (2 orders of magnitude compared to ucontext).

boost.fiber uses callcc to implement lightweight threads/fibers - the library provides fiber schedulers that allow to migrate fibers between threads. For instance one provided scheduler steals fibers from other threads if its run-queue goes out of work (fibers that are ready/that can be resumed).

(so you can choose Windows Fibers that get migrated between threads).

xlrg
  • 1,994
  • 1
  • 16
  • 14
  • 1
    Your answer is very helpful and informative, but it does not answer my question directly. Can you add an example of how to use boost.context (callcc/continuation) to migrate between threads in a safe manner (no stack corruption when cleaning a context created in another thread)? – DontCareBear Jul 23 '17 at 11:38