Subject: Re: netbsd machines get slow and hang, nfs suspected
To: None <mycroft@mit.edu>
From: Gordon W. Ross <gwr@mc.com>
List: current-users
Date: 03/26/1996 11:33:44
> From: mycroft@mit.edu (Charles M. Hannum)
> Date: 26 Mar 1996 10:35:57 -0500
> Interesting suggestion. That reminds me: The SunOS kernel has
>
> wakeone(int wchan); /* wakeup just one process */
>
> for use with things like widely used "mutex" locks, where we
> don't care who gets to proceed, and we know only one process
> will actually be allowed to proceed past the mutex.
>
> It would be nice to identify the comon places where we are
> prone to the "thundering herd" problem, and change them to
> use using wakeone() instead of wakeup().
>
> There are really a couple of different cases here:
>
> 1) tsleep() and wakeup() are being used for lock management. The real
> distinction here is whether the process being woken up needs an
> exclusive or non-exclusive lock. In this case, it should really be up
> to the tsleep() caller what happens.
>
> 2) tsleep() and wakeup() are being used to handle resource depletion.
> In this case, it's really the caller of wakeup() that knows how many
> resources just became available.
>
> It seems to me that a more flexible and less error-prone solution
> would be to write `real' lock and resource management systems. These
> aren't particularly complicated, and they would also help with
> fine-grain MP locking...
That's true, and it would be nice to have a full muliti-threaded
kernel implementation too, but I'm not holding my breath.
The wakeone() trick is trivial to implement and is easily applied
any place one has code like the following: (lots of places!)
while (foo->foo_flags & FOO_BUSY) {
foo->foo_flags |= FOO_WANTED;
tsleep((caddr_t)foo, PRIFOO, "foo", 0);
}
/* play with foo ... */
if (foo->foo_flags & FOO_WANTED) {
foo->foo_flags &= ~FOO_WANTED;
/* no point in waking more than one */
wakeone((caddr_t)foo);
}
I hope this example demonstrates how easy it is to take advantage
of the wakeone() trick in cases like this.
Gordon