Coroutines, fibers and their ilk are thread-like execution contexts managed by programming language runtimes or libraries, rather than by the operating system, which regards them to be in one tread. They are of limited use; nobody in their right mind uses such hacks when real threads are available.
It's a simplification to say that Linux uses preemptive multitasking. Like early Unix, early Linux used cooperative multitasking for running kernel code. This means that processes can be preempted while executing user space, but not while executing kernel code. While running kernel code, a process is de-scheduled to run another process only if it sleeps, which happens by making some voluntary call to some blocking function that sleeps. This approach vastly simplifies the operating system internals, because a good many race conditions go away. At least, if there is only one processor. The task which is running kernel code only has to be worried about interrupts, and those can be briefly disabled whenever they are inconvenient.
With the introduction of support for multiple processors in the experimental Linux 1.3 kernel series in the middle 1990's, that picture begun to change. A nonpreemptive kernel doesn't support SMP very well because to maintain the guarantees of cooperative multi-tasking, a big lock has to be placed around the kernel which allows only one processor to enter at a time. In Linux, this was named BKL (big kernel lock).
Gradually, the BKL came not to be enforced around all entry into the kernel, and was displaced by finer-grained SMP locks. Once you have multiple processors running inside kernel space at the same time, there is a funny situation: real concurrency is going on, protected by locking mechanisms, and yet the kernel is still cooperative in that no task can lose the processor it is running on unless it sleeps.
At that point it makes sense to just allow preemption. And so that was worked into the kernel, in the form of the option CONFIG_PREEMPT
which was experimental for many years and tended not to work consistently well across all architectures and in combination with SMP.
Why it is desirable for a kernel to be preemptible is simply that it allows for better real-time processing: shorter response times to events. While preemption is risky, most of the problems are solved by way of making SMP efficient, which tends to lower the bar for adoption of preemption: i.e. it's not a matter of "why, what for", but rather "why not".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With