bug-hurd
[Top][All Lists]
Advanced

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

Re: a recursive lock prototype


From: Marcus Brinkmann
Subject: Re: a recursive lock prototype
Date: Sat, 7 Jul 2001 03:44:38 -0500
User-agent: Mutt/1.2.5i

On Fri, Jul 06, 2001 at 10:08:25AM -0700, Thomas Bushnell, BSG wrote:
> Marcus Brinkmann <brinkmd@master.debian.org> writes:
> 
> > On Thu, Jul 05, 2001 at 08:57:15AM -0700, Thomas Bushnell, BSG wrote:
> > > Marcus Brinkmann <brinkmd@master.debian.org> writes:
> > > 
> > > > We agreed, in an inspiring coordinated coding effort, on the following
> > > > implementation (thanks to Johannes, Neal, Moshe and Rene):
> > > 
> > > No, that still has a race condition as follows.  We begin in the fully
> > > unlocked state.
> > > 
> > > THREAD 1                        THREAD 2
> > > 
> > > Start recursive_lock
> > > Read RL->locking_thread
> > >                 Context Switch
> > >                                 Start recursive_lock, function finishes   
> > >      
> > >                 Context Switch
> > > Check RL->locking_thread
> > >   it seems to match, and the lock
> > >   incorrectly succeeds.
> > > 
> > > You need some kind of guard around this structure!
> > 
> > How can the check after the second context switch succeed?
> > Thread 2 will change the value from MACH_PORT_NULL to the port name
> > of it's thread port, neither matches the port name of thread 1.
> > So the evaluation of the if condition is a constant
> > (rl->locking_thread == thread)
> 
> It's already read the name out of RL.  That "check" is just the
> comparison between two registers in Thread 1's local context.  The
> value it would check was frozen when it did the memory read before the
> first context switch.

In the fully unlocked state, RL->locking_thread is MACH_PORT_NULL.
How can this match mach_thread_self() of thread 1?

The check only succeeds if RL->locking_thread is identical to the thread's
port.  This can only be the case when I have the mutex already.

To answer your race how I see it happen:
thread 1 reads out RL->locking_thread, this gives MACH_PORT_NULL.
Thread 2 matches its thread id port against the same MAHC_PORT_NULL,
whic doesn't match, so it gets into the else and owns the lock now.
Thread 1 compares against the MACH_PORT_NULL it read out, and it
does go into the else as well, blocking on the mutex.

> > I found it really weird that no guard is needed, but actually refcount
> > is guarded by the mutex, as are all writers of the locking_thread.
> > The only unguarded reader of that is the above if, and we considered 
> > all cases we could think of and came to the conclusion that it is robust.
> 
> You were wrong, sorry to say. :)

You did not convince me yet ;)

> 



reply via email to

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