svn commit: r290649 - head/sys/arm/include
Konstantin Belousov
kib at FreeBSD.org
Tue Nov 10 12:15:14 UTC 2015
Author: kib
Date: Tue Nov 10 12:15:13 2015
New Revision: 290649
URL: https://svnweb.freebsd.org/changeset/base/290649
Log:
Implement atomic_testandset_{32,int,long,64} for ARMv6. Only
little-endian configuration for 64-bit variant is supported.
Reviewed by: mmel
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D4113
Modified:
head/sys/arm/include/atomic-v6.h
Modified: head/sys/arm/include/atomic-v6.h
==============================================================================
--- head/sys/arm/include/atomic-v6.h Tue Nov 10 12:02:41 2015 (r290648)
+++ head/sys/arm/include/atomic-v6.h Tue Nov 10 12:15:13 2015 (r290649)
@@ -593,6 +593,54 @@ atomic_store_rel_long(volatile u_long *p
*p = v;
}
+static __inline int
+atomic_testandset_32(volatile uint32_t *p, u_int v)
+{
+ uint32_t tmp, tmp2, res, mask;
+
+ mask = 1u << (v & 0x1f);
+ tmp = tmp2 = 0;
+ __asm __volatile(
+ "1: ldrex %0, [%4] \n"
+ " orr %1, %0, %3 \n"
+ " strex %2, %1, [%4] \n"
+ " cmp %2, #0 \n"
+ " it ne \n"
+ " bne 1b \n"
+ : "=&r" (res), "=&r" (tmp), "=&r" (tmp2)
+ : "r" (mask), "r" (p)
+ : "cc", "memory");
+ return ((res & mask) != 0);
+}
+
+static __inline int
+atomic_testandset_int(volatile u_int *p, u_int v)
+{
+
+ return (atomic_testandset_32((volatile uint32_t *)p, v));
+}
+
+static __inline int
+atomic_testandset_long(volatile u_long *p, u_int v)
+{
+
+ return (atomic_testandset_32((volatile uint32_t *)p, v));
+}
+
+static __inline int
+atomic_testandset_64(volatile uint64_t *p, u_int v)
+{
+ volatile uint32_t *p32;
+
+ p32 = (volatile uint32_t *)p;
+ /* Assume little-endian */
+ if (v >= 32) {
+ v &= 0x1f;
+ p32++;
+ }
+ return (atomic_testandset_32(p32, v));
+}
+
#undef ATOMIC_ACQ_REL
#undef ATOMIC_ACQ_REL_LONG
More information about the svn-src-head
mailing list