Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Nov 2015 12:15:13 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r290649 - head/sys/arm/include
Message-ID:  <201511101215.tAACFD2E022533@repo.freebsd.org>

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



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