Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Aug 2003 11:11:07 -0400
From:      "Portante, Peter" <peter.portante@hp.com>
To:        <deischen@freebsd.org>
Cc:        alpha@freebsd.org
Subject:   RE: Atomic swap
Message-ID:  <B24FABB430F7C94D942D6386447C93DC0512B55D@tayexc17.americas.cpqcorp.net>

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

-Peter

> /*
>  * Atomic swap:
>  *   Atomic (tmp =3D *dst, *dst =3D val), then *res =3D tmp
>  *
>  * void atomic_swap_long(long *dst, long val, long *res);
>  */
> static __inline=20
> void atomic_swap_long(volatile long *dst, long val, long *res)
> {
> 	u_int64_t result;
>=20
> 	__asm __volatile (
> 		"1:\tldq_l %0,%1\n\t"
			"mov %2,r1\n\t"		/* Hide under the load latency */
			"cmpeq %0,%2,r0\n\t"
			"bne r0,3f\n\t"		/* Branches out are ok, but not to targets within =
ld_l/st_c */
> 		"stq_c r1,%1\n\t"
> 		"beq r1,1b\n\t"
> 		"3:\n"
> 		: "=3D&r" (result)
> 		: "m" (*dst), "r" (val)
> 		: "memory");
>=20
> 	*res =3D result;
> }
>=20



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