From owner-freebsd-alpha@FreeBSD.ORG Thu Aug 7 12:06:36 2003 Return-Path: Delivered-To: freebsd-alpha@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0093F37B404; Thu, 7 Aug 2003 12:06:36 -0700 (PDT) Received: from zmamail03.zma.compaq.com (mailout.zma.compaq.com [161.114.64.103]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7BA9743F75; Thu, 7 Aug 2003 12:06:34 -0700 (PDT) (envelope-from peter.portante@hp.com) Received: from tayexg12.americas.cpqcorp.net (tayexg12.americas.cpqcorp.net [16.103.130.103]) by zmamail03.zma.compaq.com (Postfix) with ESMTP id D995D435E; Thu, 7 Aug 2003 15:06:33 -0400 (EDT) Received: from tayexc17.americas.cpqcorp.net ([16.103.130.15]) by tayexg12.americas.cpqcorp.net with Microsoft SMTPSVC(5.0.2195.6673); Thu, 7 Aug 2003 15:06:33 -0400 X-MimeOLE: Produced By Microsoft Exchange V6.0.6375.0 content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Date: Thu, 7 Aug 2003 15:06:33 -0400 Message-ID: X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: Atomic swap Thread-Index: AcNdFXi+nwTxVn2lQ4WZJWe1B+RoHAAAR9qz From: "Portante, Peter" To: "Marcel Moolenaar" X-OriginalArrivalTime: 07 Aug 2003 19:06:33.0741 (UTC) FILETIME=[047C93D0:01C35D17] cc: deischen@freebsd.org cc: alpha@freebsd.org Subject: RE: Atomic swap X-BeenThere: freebsd-alpha@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Porting FreeBSD to the Alpha List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Aug 2003 19:06:36 -0000 Marcel, > ---------- > From: Marcel Moolenaar > Sent: Thursday, August 7, 2003 2:55 PM > To: deischen@freebsd.org > Cc: Portante, Peter; alpha@freebsd.org > Subject: Re: Atomic swap >=20 > On Thu, Aug 07, 2003 at 01:44:18PM -0400, Daniel Eischen wrote: > > How about this? > >=20 > > static __inline void > > atomic_swap_long(volatile long *dst, long val, long *res) > > { > > u_int64_t result, temp; > >=20 > > __asm __volatile ( > > "1:\tldq %1, %3\n\t" /* load value to store */ > > "ldq_l %0, %2\n\t" /* load current value, asserting lock */ > > "stq_c %1, %2\n\t" /* attempt to store */ > > "beq %1, 2f\n\t" /* if the store failed, spin */ > > "br 3f\n" /* it worked, exit */ > > "2:\tbr 1b\n" /* *dst not updated, loop */ > > "3:\n" /* it worked */ > > : "=3D&r" (result), "=3D&r" (temp) > > : "m" (*dst), "m" (val) > > : "memory"); > >=20 > > *res =3D result; > > } >=20 > The first instruction is wrong. "val" isn't memory. Also, > forget about the branch prediction optimization. It just > makes the code unreadable and we don't even know if it > makes a difference. >=20 > The following has been written down without testing (I > dropped the cosmetic \t and instead indented by hand to > make the source code readable, not what is given to the > assembler (per se): >=20 > static __inline void > atomic_swap_long(volatile long *dst, long val, long *res) > { > __asm ( "1: ldq_l t0,%0\n" > " mov %1,t1\n" > " stq_c t1,%0\n" > " beq t1,1b\n" > " stq t0,%3\n" > :: "m"(*dst), "r"(val), "m"(*res) : "memory"); > } >=20 > In words: > o Read the current value at *dst in register t0 and lock the address. > o Since stq_c clobbers it's input and we may need to loop, save val > in temporary register t1. > o Store val at *dst (by means of t1) and if the lock failed, retry. > o Write the old value in register t0 to *res. >=20 A word of caution on performing that stq without an MB before it: = another processor cannot read that location and the destination location = and assume anything about their contents based on what they read unless = an MB is between them. > --=20 > Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net > _______________________________________________ > freebsd-alpha@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-alpha > To unsubscribe, send any mail to = "freebsd-alpha-unsubscribe@freebsd.org" >=20 >=20