From owner-freebsd-alpha@FreeBSD.ORG Thu Aug 7 10:44:20 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 0B7BA37B401; Thu, 7 Aug 2003 10:44:20 -0700 (PDT) Received: from mail.pcnet.com (mail.pcnet.com [204.213.232.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6189C43FBD; Thu, 7 Aug 2003 10:44:19 -0700 (PDT) (envelope-from eischen@vigrid.com) Received: from mail.pcnet.com (mail.pcnet.com [204.213.232.4]) by mail.pcnet.com (8.12.8/8.12.1) with ESMTP id h77HiIuN014668; Thu, 7 Aug 2003 13:44:18 -0400 (EDT) Date: Thu, 7 Aug 2003 13:44:18 -0400 (EDT) From: Daniel Eischen X-Sender: eischen@pcnet5.pcnet.com To: "Portante, Peter" In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 Reply-To: deischen@freebsd.org 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 17:44:20 -0000 On Thu, 7 Aug 2003, Portante, Peter wrote: > Dan, > > I don't think you want to do the stq_c if the location already holds the > same value. Instead, check the loaded value to see if it is the same as the The purpose of the atomic swap is to make a FIFO queueing list. The values should never be the same. It's not meant to be used as test_and_set. > value to be stored, and branch out of the loop returning the result if it is > they are the same. And starting with EV56, the need to do the branch > forward/branch back logic has been removed. And EV6 and later CPUs do such > a good job predicting the branching that it is not worth the instruction > stream space when that space can be used to avoid a stq_c. > > Additionally, the stq_c destroys the contents of %2, so you need to move the > value in %2 into another register for use in the stq_c. I don't know how to > do that in the ASM, so I just used raw register names below, highlighted in > red. How about this? static __inline void atomic_swap_long(volatile long *dst, long val, long *res) { u_int64_t result, temp; __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 */ : "=&r" (result), "=&r" (temp) : "m" (*dst), "m" (val) : "memory"); *res = result; } -- Dan Eischen