On Thu, Jan 26, 2006 at 04:02:45PM +0100, Jens M Andreasen wrote:
On Thu, 2006-01-26 at 11:54 +0000, James
Courtier-Dutton wrote:
Thread A will only get the lock if the kernel
happens to do a task
switch between Thread B to Thread A.
Not according to posix. Perhaps all this talk about "aquiring the lock"
is what confuses us, suggesting that A has to be competitively active to
get anything. Instead it is the running thread that giveth the lock
away ...
Again, according to posix.
That is probably an accurate description. In one possible implementation,
the lock has a priority-ordered list of threads waiting for it. Inside
the unlock call, the thread at the head of the list (if any) is removed
from the list, gets the lock, and is added to another priority ordered
list of runnable threads. If its priority is higher than the current
one, its also gets the CPU. In other words, the new thread gets the lock
even before it runs again, and the original owner can't take it back.
But there is a completely different (but not very efficient) way to
do this sort of thing. In this model, waiting for something (e.g. a
lock) involves trying to get it inside a loop, and going to sleep
when that fails. When for example a lock is released, all threads that
could be waiting for it (or even in the limit all threads that are
waiting for anything) are woken up, and when rescheduled and running
again, try one more iteration of the loop. One of them will succeed
and all the others will fail and go to sleep again. In such a system,
the lock is not effectively taken until the new owner is actually
running, and the original owner could take it back if it continues
after the unlock. This method can involve a *lot* of rescheduling
that is just a waste of time. But early UNIX kernels worked like
this AFAIK (using hash lists to limit the number of wasted wakeups).
--
FA