PortOS Project 2 FAQ
Frequently asked questions:
Missed Interrupts
I have measured the time interval between invocations of the
clock handler and it's more than the value of PERIOD defined in
clock.h. What's going on?
A clock interrupt is only raised when it's "safe" to do so. When
the clock timer goes off, indicating a clock interrupt should be
raised, a check is made to make sure the currently running thread
is executing safe code, which is not part of an NT-supplied
library. Since we have no control over what a thread might do in a
library, it's risky to interrupt it. For instance, a thread could
be interrupted in the middle of a printf(), when it's holding an NT
lock. The context-switch might start another thread which also
calls printf(), cannot get the lock, and blocks, causing a deadlock.
Preemption and Performance
Why does PortOS run more slowly when preemption is
turned on?
Getting user-level threads preemption to work
correctly in Windows NT requires some extra kernel threads to trigger
clock interrupts and make the interrupt handler run and exit cleanly,
which compete for CPU time with the NT kernel thread running the
minithreads. Basically, the design of timers in NT makes an efficient
implementation difficult.
No Runnable Threads
What do I do if no thread is available to run on a context
switch (i.e. all threads are blocked)?
This situation could arise if all the threads in the system are
blocked on semaphores or waiting for alarms. The clock interrupt
mechanism we have given you assumes that there is always a thread
running, ready to take the interrupt. This means that you have to
create an "idle thread", which is ready to run if all the other
threads are blocked, but does nothing (i.e. runs a function which
loops infinitely, or yields infinitely). The idle thread should only
run if all other threads are blocked, so it should not go on run queue
with all the normal threads, and should never block!
Emin Gün Sirer, May 2002