Alright, so with the new architectures reviewed in mind, here’s my second attempt at creating a portable interrupt handler design for this OS :
To work, this interrupt handler design assumes presence of the following :
- Interrupt hardware (duh), that is a way to run a code snippet of arbitrary length in the event of an interrupt, and to know what code was running before interrupt in order to go back to it later or kill it if there’s no way back.
- A working thread system with pop-up threading facilities (see below).
This OS, like many other microkernel-based ones, is based on a set of processes which provide services to each other. The way for another process to benefit from such services is to spawn a thread within the responsible process to take care of the job. This approach is called “pop-up threads”, and has multiple benefits, one of them being that it makes it trivial to enforce that poor code within the called process cannot crash the caller.
Before a service can be used by other processes, the process which provides said service has to tell the OS about its service provider status, once it’s initialized and ready to actually provide the service. As part of this procedure, it has access to some settings about how pop-up threads work. This is still heavily WIP, as an example I’ve not decided yet how services which return a result work, but among these settings has to be at which priority the provider process wants the pop-up threads to run and whether pop-up threads can run in parallel (threaded operation) or must be run in a sequential fashion, in a first come – first served basis (asynchronous operation). The former is obviously significantly better for scalability, but the latter is significantly easier to code, I leave it up to developers to see which model they choose, depending on what matters most to them on each individual project. Myself, I’m a bit of a perfectionist, so I’d chose scalability any day over coding comfort, but I don’t want to impose that kind of personal choices on others.
Interrupt handling algorithm
- This algorithm uses a global handler for all interrupts. For interrupt hardware like x86’s that does not provide an easy way to know which interrupt has occurred and heavily favors a vectored interrupt model, we have created lots of tiny interrupt vectors that simply store the interrupt vector number on the kernel stack (or whatever else “safe” storage facility is available) and switch to a global interrupt handler.
- Make sure that interrupts are disabled and that we’re in a suitable setup for running kernel-mode code.
- Save the previously running thread’s state, just as if the scheduler was going to switch to another thread.
- Check which process is set to handle this interrupt, and spawn a pop-up thread within this process to take care of the interrupt.
- Enable interrupts again.
- Can the newly created pop-up thread run immediately ? (Process previously had no running thread or has a threaded pop-up thread model)
- If so, switch to it for optimal interrupt handling reactivity.
- If not, switch back to the previously running thread.