[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: a recursive lock prototype

From: Thomas Bushnell, BSG
Subject: Re: a recursive lock prototype
Date: 04 Jul 2001 18:13:23 -0700
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7

Maybe I missed something, but what specifically is this for?  

Anyway, on to more substantive comments:

moshez@zadka.site.co.il writes:

> struct recursive_lock
> {
>   spin_lock_t protection;
>   int locked;
>   struct mutex mutex;
> };

What is the separate "protection" bit for?

> void
> recursive_lock (struct recursive_lock *lock)
> {
>   spin_lock (&lock->protection);
>   if (lock->locked)
>     {
>       lock->locked++;
>       spin_unlock (&lock->protection);
>     }
>   else
>     {
>       spin_unlock (&lock->protection);
>       mutex_lock (&lock->mutex) spin_lock (&lock->protection);
>       lock->locked = 1;
>       spin_unlock (&lock->protection);
>     }
> }

What are the expected semantics of this function?  (A complete
implementation of something always includes explanatory comments.)  

The usual job of a mutual exclusion lock is to block at least
sometimes.  My analysis is that your function never blocks under
normal circumstances.  Any block would happen inside a call to
spin_lock or a call to mutex_lock.

But LOCK->protection is never held but for brief periods to apparently
prevent races on LOCK->locked.  So users never block waiting for that

And LOCK->mutex is only locked when LOCK->locked was zero and the lock
was already unlocked, so the attempt to lock it succeeds.

Well, actually no!  There's a race condition it seems to me, if the
lock is in the fully unlocked state, and two users call recursive_lock
at the same time.  If they called one after the other (in very close
succession), note that both would succeed quickly, and LOCK->locked
would have the value 2.  But if they are really close, then consider:

THREAD 1                        THREAD 2
Locks "protection"
Checks "locked"
Unlocks "protection"
            Context Switch
                                Call to recursive_lock completes fully
                                  leaving "mutex" locked.
            Context Switch
Locks "mutex": Blocks until 
  unlock releases mutex.

But this behavior is not stable across scheduling re-orders.  If
Thread 1 is allowed to complete its call before Thread 2 starts, then
we have something totally different.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]