From owner-freebsd-net Tue Dec 12 19:47:33 2000 From owner-freebsd-net@FreeBSD.ORG Tue Dec 12 19:47:30 2000 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from fw.wintelcom.net (ns1.wintelcom.net [209.1.153.20]) by hub.freebsd.org (Postfix) with ESMTP id 6BBAA37B400 for ; Tue, 12 Dec 2000 19:47:30 -0800 (PST) Received: (from bright@localhost) by fw.wintelcom.net (8.10.0/8.10.0) id eBD3lTG05005; Tue, 12 Dec 2000 19:47:29 -0800 (PST) Date: Tue, 12 Dec 2000 19:47:29 -0800 From: Alfred Perlstein To: Garrett Wollman Cc: net@FreeBSD.ORG Subject: Re: MEXT_IS_REF broken. Message-ID: <20001212194728.S16205@fw.wintelcom.net> References: <20001211014837.W16205@fw.wintelcom.net> <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> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i 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 Sender: bright@fw.wintelcom.net Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org * Garrett Wollman [001212 18:50] wrote: > < 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