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 _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"