So far our kernel has been running a single stream of code, initializing various parts of the cpu and system hardware in sequence and handling interrupts from few sources.
While it is possible to go further, we’ll begin to run into a handful of problems. Some devices take time to perform actions, and our code may need to wait. If we have a lot of devices, this can lead to things becoming very slow. What if we want to start running multiple threads, or even multiple programs with multiple threads? This is a common scenario, and what the scheduler is responsible for.
The scheduler is similar to a hardware multiplexer (mux) in that it takes multiple inputs (programs or threads) and allows them to share a single output (the cpu executing the code).
The scheduler does this by interrupting the current stream of code, saving its state, selecting the next stream, loading the new state and then returning. If done at a fast enough rate, all programs will get to spend a little time running, and to the user it will appear as if all programs are running at the same time. This whole operation is called a context switch.
For our examples the scheduler is going to do its selection inside of an interrupt handler, as that’s the simplest way to get started. As always, there are other designs out there.
This part will cover the following areas: