cvs commit: src/sys/kern kern_umtx.c src/sys/sys proc.h
jhb at FreeBSD.org
Thu Jul 17 10:02:48 PDT 2003
On 17-Jul-2003 Mike Makonnen wrote:
> On Thu, Jul 17, 2003 at 09:12:30AM -0400, John Baldwin wrote:
>> > ...
>> > 2. Once a umtx was contested all future locks and unlocks
>> > were happening in the kernel, regardless of whether it
>> > was contested or not. To prevent this from happening,
>> > when a thread locks a umtx it checks the queue for that
>> > umtx and unsets the contested bit if there are no other
>> > threads waiting on it. Again, this is slightly more
>> > complicated than it needs to be because we can't hold
>> > a lock across casuptr(). So, the thread has to check
>> > the queue again after unseting the bit, and reset the
>> > contested bit if it finds that another thread has put
>> > itself on the queue in the mean time.
>> > ...
>> The in-kernel mutexes handle this case during the unlock
>> routine. When unlocking a contested mutex, if there is only
>> one waiter, we wake up that waiter and set the lock cookie
>> to MTX_UNOWNED without the contested bit set. If the woken
>> thread is the only thread to try to acquire the lock, it
>> suceeds and the lock remains uncontested until another thread
>> blocks trying to lock it. This would mean that the next lock of
>> the lock would not need to bounce into the kernel if the lock
>> was not owned by anyone.
> Initially I was going to do it this way. But there were a couple of
> things that concerned me so I thought it would be safer to implement
> it the way I did. One of them is that it opens up a race between a
> thread that is trying to acquire the umtx for the first time, and the
> thread that the unlocker just woke up. I suppose we could introduce
> a UMTX_RESERVED or something (UMTX_UNOWNED is already used) that no
> one except a thread that just woke up could lock. Is that what you
> are suggesting?
There is no race there. If both threads want the lock, one will
suceed and the other will block on it and have to mark the lock as
contested. This is how that works with the kernel mutexes. This
does mean that you need to loop in the umtx_lock() function in the
kernel and that you need to allow for the fact that you may be
trying to acquire an uncontested, unowned mutex.
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!" - http://www.FreeBSD.org/
More information about the cvs-all