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>