Skip site navigation (1)Skip section navigation (2)
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>