Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Aug 2007 22:02:13 +0200
From:      Maciej Sobczak <prog@msobczak.com>
To:        Pawel Jakub Dawidek <pjd@FreeBSD.org>
Cc:        freebsd-arch@FreeBSD.org
Subject:   Re: Lockless uidinfo.
Message-ID:  <46C75045.8000503@msobczak.com>
In-Reply-To: <20070818161449.GE6498@garage.freebsd.pl>
References:  <20070818120056.GA6498@garage.freebsd.pl>	<20070818142337.GW90381@elvis.mu.org>	<20070818150028.GD6498@garage.freebsd.pl>	<20070818155041.GY90381@elvis.mu.org> <20070818161449.GE6498@garage.freebsd.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
Pawel Jakub Dawidek wrote:

> thread1 (uifind)		thread2 (uifree)
> ----------------		----------------
> 				refcount_release(&uip->ui_ref))
> 				/* ui_ref == 0 */
> mtx_lock(&uihashtbl_mtx);
> refcount_acquire(&uip->ui_ref);
> /* ui_ref == 1 */
> mtx_unlock(&uihashtbl_mtx);
> 				mtx_lock(&uihashtbl_mtx);
> 				if (uip->ui_ref > 0) {
> 					mtx_unlock(&uihashtbl_mtx);
> 					return;
> 				}
> 
> Now, you suggest that ui_ref in 'if (uip->ui_ref > 0)' may still have
> cached 0? I don't think it is possible, first refcount_acquire() uses
> read memory bariers (but we may still need ui_ref to volatile for this
> to make any difference) and second, think of ui_ref as a field protected
> by uihashtbl_mtx mutex in this very case.
> 
> Is my thinking correct?

Yes, but I believe you are too conservative even with the above explanation.

Unlocking (thread1) and subsequent locking (thread2) of the same mutex 
guarantees memory visibility between threads, at least if the mutex 
provides the fundamental release-acquire consistency. In this case, the 
memory barrier is part of this process itself and you don't need to do 
anything else to guarantee the visibility of ui_ref == 1 in thread2.

The only thing to worry about is caching of values in CPU registers 
(note that this issue is separate from visibility), but these should be 
prevented by the compiler at the point of mtx_lock. There are basically 
two ways to guarantee it: either the compiler is too stupid/conservative 
to cache the value across mtx_lock if it's a function call, or it is 
smart enough to know (or just see) that there is a membar inside. In any 
case no register-level caching will take place.

There should be no need to make anything volatile.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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