How Programming Languages Model Asynchronous Program Flow 36 One unexpected downside of this is that most OS schedulers make sure all threads get some time to run by giving each OS thread a time slice where it can run before the OS pre-empts the thread and schedules a new thread on that CPU. A program using many OS threads might be allotted more time slices than a program with fewer OS threads. A program using M:N threading will most likely only use a few OS threads (one thread per CPU core seems to be the starting point on most systems). So, depending on whatever else is running on the system, your program might be allotted fewer time slices in total than it would be using many OS threads. However, with the number of cores available on most modern CPUs and the typical workload on concurrent systems, the impact from this should be minimal. FFI Since you create your own stacks that are supposed to grow/shrink under certain conditions and might have a scheduler that assumes it can pre-empt running tasks at any point, you will have to take extra measures when you use FFI. Most FFI functions will assume a normal OS-provided C-stack, so it will most likely be problematic to call an FFI function from a fiber/green thread. Y ou need to notify the runtime scheduler, context switch to a different OS thread, and have some way of notifying the scheduler that you're done and the fiber/green thread can continue. This naturally creates overhead and added complexity both for the runtime implementor and the user making the FFI call. Advantages It is simple to use for the user. The code will look like it does when using OS threads. Context switching is reasonably fast. Abundant memory usage is less of a problem when compared to OS threads. Y ou are in full control over how tasks are scheduled and if you want you can prioritize them as you see fit. It's easy to incorporate pre-emption, which can be a powerful feature. Drawbacks Stacks need a way to grow when they run out of space creating additional work and complexity Y ou still need to save the CPU state on every context switch It's complicated to implement correctly if you intend to support many platforms and/or CPU architectures FFI can have a lot of overhead and add unexpected complexity