On Tue, Jun 10, 2003 at 01:04:48AM +0530, Linux Newbie wrote: > following the function down_trylock .. i got to __down_trylock.. > /* > * Add "everybody else" and us into it. They aren't > * playing, because we own the spinlock. > */ > if (!atomic_add_negative(sleepers, &sem->count)) > > ----->>> wake_up(&sem->wait); <<<---- > > spin_unlock_irqrestore(&semaphore_lock, flags); > return 1; > > Why is it waking up the sleeping process here? Isnt down_trylock supposed > to 'try to' acquire the sem, and if cant then to simply return imm. > And shouldnt wake_up be called only when 'releasing' a semaphore via the > up() function call? I am not intimate with this code. However, I am willing to wager a guess that this check is necessary to prevent race conditions. Consider what happens when process A calls down_trylock(). A will decrement the count, then see if it the decrement worked (still positive). If the down() wasn't sucessful, this function must fix up the mess. Now, insert process B performing an up() on the same semaphore -after- process A decremented the count, but before this "fixup" routine is called. Process B's up() call will not wake any processes (because this process couldn't get the lock, but -did- make the count one number further negative, there aren't any available "resources" freed up, so there are no processes to wake..). However, the chances exists that B -should- have woken a process. So, if the atomic_add_negative() returns 0, the test will discover that process A is now responsible for waking other processes that may be sleeping on this semaphore. If I'm barking up the wrong tree, I trust someone will correct my mistakes. -- Demand voting integrity: http://verify.stanford.edu/evote.html
Attachment:
pgp00440.pgp
Description: PGP signature