On Monday, March 19, 2012 7:53:43 pm David Xu wrote:
> On 2012/3/20 1:50, John Baldwin wrote:
> > On Monday, March 19, 2012 11:41:53 am David Xu wrote:
> >> On 2012/3/19 20:33, John Baldwin wrote:
> >>> On Saturday, March 17, 2012 8:22:29 pm David Xu wrote:
> >>>> Author: davidxu
> >>>> Date: Sun Mar 18 00:22:29 2012
> >>>> New Revision: 233103
> >>>> URL: http://svn.freebsd.org/changeset/base/233103
> >>>>
> >>>> Log:
> >>>>     Some software think a mutex can be destroyed after it owned it, for
> >>>>     example, it uses a serialization point like following:
> >>>>          pthread_mutex_lock(&mutex);
> >>>>          pthread_mutex_unlock(&mutex);
> >>>>          pthread_mutex_destroy(&muetx);
> >>>>     They think a previous lock holder should have already left the mutex 
> >>>> and
> >>>>     is no longer referencing it, so they destroy it. To be maximum 
> >>>> compatible
> >>>>     with such code, we use IA64 version to unlock the mutex in kernel, 
> >>>> remove
> >>>>     the two steps unlocking code.
> >>> But this means they destroy the lock while another thread holds it?  That
> >>> seems wrong.  It's one thing if they know that no other thread has a 
> >>> reference
> >>> to the lock (e.g. it's in a refcounted object and the current thread just
> >>> dropped the reference count to zero).  However, in that case no other 
> >>> thread
> >>> can unlock it after this thread destroys it.  Code that does this seems 
> >>> very
> >>> buggy, since if the address can be unmapped it can also be remapped and
> >>> assigned to another lock, etc., so you could have a thread try to unlock a
> >>> lock it doesn't hold.
> >> They have handshake code to indicate that the mutex is no longer used by
> >> previous
> >> holder. e.g:
> >>
> >> thread 1:
> >>       pthread_mutex_lock(&mutex);
> >>       done = 1;
> >>       pthread_mutex_unlock(&mutex);
> >> thread 2:
> >>       pthread_mutex_lock(&mutex);
> >>       temp = done;
> >>       pthread_mutex_unlock(&mutex);
> >>       if (temp == 1)
> >>           pthread_mutex_destroy(&mutex);
> > Hmm, so how does this result in the crash you fixed?  That is, thread 1 has
> > to fully finish pthread_mutex_unlock() before thread2's pthread_mutex_lock()
> > can succeed, so I don't see how thread 1 could still be in
> > pthread_mutex_unlock() when thread 2 calls pthread_mutex_destroy().
> This is implementation detail,thread1 does unlocking in two steps:
> first it clears lock bit, but leaves contention bit there,
> then thread2 enters and sets lock bit, and then destroy it.
> T1:
>     clear lock bit, contention bit is still set.
> T2:
>     lock the mutex by setting lock bit.
>     do some work.
>     unlock the mutex by clearing lock it,
>       enters kernel, and see no waiters, clears contention bit.
>     destroy the mutex, unmap memory
> T1:
>     enter kernel to clear contention bit, because the memory
>     is unmmaped, it returns EINVAL.

Ah, ok.  So we should still be able to do an uncontested unlock
in userland directly.

-- 
John Baldwin
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to