Date: Tue, 12 Dec 2000 19:47:29 -0800 From: Alfred Perlstein <bright@wintelcom.net> To: Garrett Wollman <wollman@khavrinen.lcs.mit.edu> Cc: net@FreeBSD.ORG Subject: Re: MEXT_IS_REF broken. Message-ID: <20001212194728.S16205@fw.wintelcom.net> In-Reply-To: <200012130250.VAA55319@khavrinen.lcs.mit.edu>; from wollman@khavrinen.lcs.mit.edu on Tue, Dec 12, 2000 at 09:50:19PM -0500 References: <20001211014837.W16205@fw.wintelcom.net> <Pine.BSF.4.21.0012111223350.21769-100000@jehovah.technokratis.com> <20001212014429.Y16205@fw.wintelcom.net> <20001212015059.Z16205@fw.wintelcom.net> <20001212143214.H2312@canonware.com> <20001212175937.M16205@fw.wintelcom.net> <200012130250.VAA55319@khavrinen.lcs.mit.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
* Garrett Wollman <wollman@khavrinen.lcs.mit.edu> [001212 18:50] wrote:
> <<On Tue, 12 Dec 2000 17:59:37 -0800, Alfred Perlstein <bright@wintelcom.net> said:
>
> > Actually, in truth I think you can get the code right like so:
>
> > long x = _mmm->m_ext.ref_cnt->refcnt;
> > while (!atomic_cmpset_long(&_mmm->m_ext.ref_cnt->refcnt, x - 1, x))
> > ;
>
> Cool! You've just (almost) reinvented non-blocking parallel
> reference-counts. Of course, what you really need is:
>
> long
> atomic_decrement_long(long *where)
> {
> long oldval;
>
> do {
> oldval = *where;
> } while (compare_exchange(where, &oldval, oldval - 1) != FAILURE);
>
> return (oldval);
> /*
> * Five instructions in-line on i486.
> * 1: movl (%ebx), %eax
> * movl %eax, %edx
> * subl $1, %edx
> * cmpxchg (%ebx), %eax, %edx ; IIRC -- might be backwards
> * jc 1
> */
> }
Yeah, oops. :)
It just goes to show how HAVING A CLEAR API for doing this might
actually help us AVOID RACE CONDITIONS. *cough*
>
> ...except that on some architectures, the right way to write it would
> be:
>
> long
> atomic_decrement_long(long *where)
> {
> long oldval;
>
> do {
> oldval = load_linked_long(where);
> } while (store_conditional(where, oldval - 1) != FAILURE);
>
> return (oldval);
> /*
> * Compiles to four or five instructions on an Alpha.
> */
> }
>
> In this particular instance, you know that you just deleted the last
> reference if atomic_decrement_long returns an `old value' of
>
> > But that's just gross, expensive and shouldn't be needed.
>
> Nothing gross about it -- just ask any parallel algorithms geek. (Of
> which I am emphatically not one, I should point out.)
What Jason seems to be implying is that I must inline these functions
by hand each time I want to do this instead of having an API for it.
That's gross.
--
-Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org]
"I have the heart of a child; I keep it in a jar on my desk."
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001212194728.S16205>
