Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Aug 2003 13:44:18 -0400 (EDT)
From:      Daniel Eischen <eischen@vigrid.com>
To:        "Portante, Peter" <peter.portante@hp.com>
Cc:        alpha@freebsd.org
Subject:   RE: Atomic swap
Message-ID:  <Pine.GSO.4.10.10308071320370.9489-100000@pcnet5.pcnet.com>
In-Reply-To: <B24FABB430F7C94D942D6386447C93DC0512B55D@tayexc17.americas.cpqcorp.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.10.10308071320370.9489-100000>