Multi-threading
Multithreading in JNode involves the scheduling on multiple java.lang.Thread instances onto 1 or more processors. (Multi processor support is still a wish). It follows the yieldpoint scheduling idea.
Yieldpoint scheduling
Yieldpoint scheduling means that every thread gives up the processor at regular intervals to let other threads run. A more precise description is that the native code compiler emits yieldpoints at certain instructions. These instructions are at the beginning and end of a method, backward jumps, methods invocations. A yieldpoint checks if a "yield" flag has been set, and if so, issues a yield (software-)interrupt. The kernel takes over and schedules a new thread.
The "yield" flag can be set by a timer interrupt, or by the (kernel) software itself, e.g. when doing an explicit yield or in case of locking synchronization methods.
The scheduler invoked by the (native code) kernel is implemented in the VmProcessor class. This class (one instance for every processor) contains a list of threads ready to run, a list of sleeping threads and a current thread. On a reschedule, the current thread is appended to the end of the ready to run thread-list. Then the sleep list is inspected first for threads that should wake-up. These threads are added to the ready to run thread-list. After that the first thread in the ready to run thread-list is removed and used as current thread. The reschedule method returns and the (native code) kernel does the actual thread switching.
The scheduler itself runs in the context of the kernel and cannot be interrupted. Therefor a special flags it self that prevents yieldpoints for issueing yield-interrupts.
Thread priorities
Thread can have different priorities, ranging from Thread.LOW_PRIORITY to Thread.HIGH_PRIORITY. In JNode these priorities are implemented via the ready to run thread-list. This list is (almost) always sorted on priority, which means that the threads with the highest priority comes first.
There is one exception on this rule, which is in the case of busy-waiting in the synchronization system. Claiming access to a monitor (internals) involves a busy-waiting loop with an explicit yield. This yield ignores the thread priority to avoid starvation of lower-priority threads, which will lead to an endless waiting time for the high priority thread.
Classes involved
The following classes are involved in the scheduling system. All of these classes are in the org.jnode.vm package.
- VmProcessor
- VmThread contains the internal (JNode specific) data for a single thread. This class is extended for each specific platform

i need this info
Hi,
thanks for this piece of documentation.
Andreas
Why yieldpoints vs. scheduling directly from timer interrupt?
The explanation is quite clear, so a fiew questions on background of scheduling model arised for me:
What is the Idea behind introducing some overhead by means of compiling-in yieldpoints to native code?
Is it a problem when a thread looses control (and context switches to other thread) in the middle of operation which is sujested to be "quantum" from point of view of JVM ? For example a lot of architectures save/restore floating point coprocessor registers in the middle of fp calculations...
It's also likely that future processors or Java targeted ASIC-s would have some special hardware facilities for Java task switching
Why yieldpoints
The problem here is support for garbage collection.
The GC system needs to now where there are references to object in order to allow for exact garbage collection (or to move objects in memory).
If you allow threads to be interrupted anywhere, this would mean that you would need GC information for ALL points in the code. This would be to expensive in terms of memory usage.
By only allowing thread switches at yieldpoints, you can limit the amount of GC info that is needed.
Ewout