Kyu is a real time operating system (RTOS). Exactly what is an "operating system" you might ask. My definition is that it is a platform to aid the writing and running of software. An operating system is what gives computing hardware its "personality".
What makes an operating system real time. I argue that strict unfairness is what makes an operating system real time. An operating system has entities that can be scheduled, these entities have priorities, and at any point in time the highest priority entity is running. Period. When the situation changes such that a new entity is the highest priority "ready to run" entity, the system transitions to running it as quickly as possible.
In Kyu we call the entities "threads". Threads are assigned priorities with low numbers being more important. The system is always running some thread. The key primitives that affect scheduling are thr_block() and thr_unblock(). A thread may ask that it be blocked by calling thr_block(). A thread can only block itself, a thread cannot be blocked by another thread. Another thread can call thr_unblock ( thread), with the argument being the thread to be unblocked. If that thread is already unblocked, then the unblock() call is a noop. Otherwise the target thread is marked ready and the system decides whether it should immediately be caused to run. If it has a lower priority number than the currently running thread it should and will be.
There is the essential core of Kyu. A number of conveniences are built on top of this. Semaphores are one (but are implemented in terms of thr_block and thr_unblock). Kyu also provides a number of important and convenient facilities for timer and interrupt management. A vital feature is the ability to perform a thr_unblock (and hence a sem_unblock) from interrupt code which has no thread context. The system may be running one thread, an interrupt can occur, the interrupt code can decide to unblock a blocked thread, then when the system returns from the interrupt, it will return to the thread that was just unblocked (if it has a lower priority number than the thread that was originally interrupted.
The vital assertion that is always maintained is that the thread with the lowest priority number that is in a state "ready to run" is in fact always running. The only exception being interrupt code, or code that is running to perform the transition to "making it so".
Kyu has 3 different ways of keeping the state necessary to resume a thread. If you look at the thread listing from the "l" command you will see the letters J, I, and C marked on different threads.
Thread: name ( &tp ) state pc sp pri * Thread: shell (400a7998) READY J 40010494 40568000 11 Thread: net (400a75d8) SEM J 40010494 40578000 12 Thread: net_slow (400a74e8) REPEAT C 40015a64 4057c000 13 Thread: tcp-bsd (400a77b8) SEM I 400108fc 40570000 14 Thread: tcp-timer (400a76c8) READY C 40023c34 40574000 15 Thread: wangdoodle (400a7308) SEM J 40010494 40584000 30 Thread: wang_thr (400a73f8) READY I 400104f8 40580000 31 Thread: idle (400a78a8) READY C 40010950 4056c000 1234The above is a typical result from a running system. The "*" mark on the left side shows the currently running thread. As it turns out this is always the "shell" since the shell must be running for the "l" command to be run. But let us talk about the three ways that a thread may be suspended and resumed.
The simplest is "J" (for jump). This is pretty much like setjmp/longjmp in the C language. The thread called thr_block at some point and this saves "J" information to resume the thread.
Perhaps unexpected is "I" (for interrupt). Here a thread was interrupted by (of all things) a hardware interrupt. I could perhaps be a timer, or it could be the network, serial port, or anything that can generated hardware interrupts. When it came time to return from the interrupt, Kyu reviewed the situation and found that it should resume some other thread which was now most important (there is a good phrase). Perhaps a thread was waiting on a timer event and a timer interrupt is what just happened.
The "C" (for continuation) is somewhat novel. Here almost no state is preserved. The thread simply "comes to life" again as though it was being started for the first time. This can be useful for threads that need to be run again and again to do exactly the same thing, which is often of brief duration, then they exit and wait to be activated again. In the above listing the "net_slow" thread is just this sort of thing. It runs periodically (as indicated by the "REPEAT" state (but we aren't talking about states just yet).
Kyu / [email protected]