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>