Information Technology Reference
In-Depth Information
Then, acquiring a free lock or releasing a lock that has no waiting threads can
be done with a few instructions executed by the user-level thread and without
a system call. A system call is still needed when the fast path fails (e.g., when
the thread needs to remove itself from the ready list, add itself to the waiting
list, and suspend execution.) We leave the details of such an implementation as
an exercise for the reader.
User-level threads. In a threads library that operates completely at user
level, the kernel provides just one thread to a process, and the process multi-
plexes user-level threads over that one virtual processor. The situation is similar
to the kernel-level threads case, except everything operates in a process's ad-
dress space rather than in the kernel's address space. In particular, all of the
code, shared state, lock data structures, thread control blocks, and the ready
list are in the process's address space.
Lock implementations based on disabling interrupts change only slightly. A
user-level threads package cannot disable interrupts; the kernel can not allow
an untrusted process to disable interrupts and potentially run forever. Instead,
it can disable signals from the operating system, which effectively accomplishes
the same thing: just as a thread in a kernel-level threads package running
on a uniprocessor machine can make a set of operations atomic by disabling
interrupts before the operations and enabling them at the end, a thread in a
user-level threads package that multiplexes user-level threads over one kernel
thread can make a set of operations atomic by disabling signals before the
operations and disabling them at the end.
Implementations based on atomic read-modify-write instructions need no
changes at all.
5.5.2
Implementing condition variables
We can implement condition variables using the same techniques we use to
implement locks.
To illustrate the similarity, Figure ?? shows a implementation of condition
variables for a kernel-level threads based on atomic read-modify-write instruc-
tions. There are few changes from the lock implementation for that environment
shown in Figure 5.12 on page 216. For example, as in the lock implementation,
we still disable interrupts to ensure that once a thread removes itself from the
ready list it puts itself onto the waiting list.
This implementation provides Hansen semantics|when we signal a waiting
thread, that thread becomesReady, but it may not run immediately, and it
still must reacquire the lock. It is possible for another thread to acquire the
lock first and to change the state guarded by the lock before the waiting thread
returns from Cond::Wait() .
 
Search WWH ::




Custom Search