Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Sep 2010 09:02:18 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        Benjamin Kaduk <kaduk@mit.edu>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Questions about mutex implementation in kern/kern_mutex.c
Message-ID:  <201009170902.18748.jhb@freebsd.org>
In-Reply-To: <alpine.GSO.1.10.1009162317430.9337@multics.mit.edu>
References:  <20100915134415.GA23727@pm513-1.comsys.ntu-kpi.kiev.ua> <201009161416.05759.jhb@freebsd.org> <alpine.GSO.1.10.1009162317430.9337@multics.mit.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday, September 16, 2010 11:24:29 pm Benjamin Kaduk wrote:
> On Thu, 16 Sep 2010, John Baldwin wrote:
> 
> > On Thursday, September 16, 2010 1:33:07 pm Andrey Simonenko wrote:
> >
> >> The mtx_owned(9) macro uses this property, mtx_owned() does not use anything
> >> special to compare the value of m->mtx_lock (volatile) with current thread
> >> pointer, all other functions that update m->mtx_lock of unowned mutex use
> >> compare-and-set instruction.  Also I cannot find anything special in
> >> generated Assembler code for volatile variables (except for ia64 where
> >> acquire loads and release stores are used).
> >
> > No, mtx_owned() is just not harmed by the races it loses.  You can certainly
> > read a stale value of mtx_lock in mtx_owned() if some other thread owns the
> > lock or has just released the lock.  However, we don't care, because in both
> > of those cases, mtx_owned() returns false.  What does matter is that
> > mtx_owned() can only return true if we currently hold the mutex.  This works
> > because 1) the same thread cannot call mtx_unlock() and mtx_owned() at the
> > same time, and 2) even CPUs that hold writes in store buffers will snoop their
> > store buffer for local reads on that CPU.  That is, a given CPU will never
> > read a stale value of a memory word that is "older" than a write it has
> > performed to that word.
> 
> Sorry for the naive question, but would you mind expounding a bit on what 
> keeps the thread from migrating to a different CPU and getting a stale 
> value there?  (I can imagine a couple possible mechanisms, but don't know 
> enough to know which one(s) are the real ones.)

The memory barriers in the thread_lock() / thread_unlock() pair of a context
switch ensure that any writes posted by the thread before it performs a context
switch will be visible on the "new" CPU before the thread resumes execution.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009170902.18748.jhb>