An interesting case is a different Google fiber library, not open-sourced but described in a public talk. [1] Real kernel threads but (mostly) scheduled in userspace via new syscalls [2] that suspend the current thread and unsuspend a userspace-chosen other thread. The idea is that most of the overhead of kernel threads is the scheduling and userspace has the ability to make a quick good choice. [3] Thus you can get most of the CPU performance of an async implementation but the relatively easy-to-read callback-free code of a threaded implementation. Anyway, people can disagree on what to call such a combination.
[1] https://www.youtube.com/watch?v=KXuZi9aeGTw
[2] the rseq stuff described in that talk has been upstreamed [4] but the switchto stuff still hasn't.
[3] I'm not sure if the performance argument is as strong since the Meltdown/Spectre mitigations added to the performance cost of any syscall.
[4] https://www.efficios.com/blog/2019/02/08/linux-restartable-s...
In short:
- The key difference between fibers and kernel threads is that fibers use cooperative context switching
- When a coroutine yields, it passes control directly to its caller (or, in the case of symmetric coroutines, a designated other coroutine).
- When a fiber blocks, it implicitly passes control to the fiber scheduler. Coroutines have no scheduler because they need no scheduler
Here's[2] a fun/interesting 15 year old blog post explaining some of the use cases and pitfalls of using Win32 fibers.
[1]: https://jeffpar.github.io/kbarchive/kb/128/Q128531/ (CreateFiber)
[2]: https://docs.microsoft.com/en-us/archive/blogs/larryosterman...