Date: Thu, 1 Aug 2013 23:51:20 +0000 (UTC) From: Jung-uk Kim <jkim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253875 - in projects/atomic64/sys: amd64/include i386/include Message-ID: <201308012351.r71NpKxk092536@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jkim Date: Thu Aug 1 23:51:20 2013 New Revision: 253875 URL: http://svnweb.freebsd.org/changeset/base/253875 Log: Add a new atomic operation atomic_testandset for x86. This operation atomically tests and sets a bit, i. e., tmp = (*p & v) != 0; *p |= v; return (tmp) where v = (<type>)1 << s % (sizeof(<type>) * NBBY) Modified: projects/atomic64/sys/amd64/include/atomic.h projects/atomic64/sys/i386/include/atomic.h Modified: projects/atomic64/sys/amd64/include/atomic.h ============================================================================== --- projects/atomic64/sys/amd64/include/atomic.h Thu Aug 1 23:38:57 2013 (r253874) +++ projects/atomic64/sys/amd64/include/atomic.h Thu Aug 1 23:51:20 2013 (r253875) @@ -82,6 +82,8 @@ int atomic_cmpset_int(volatile u_int *ds int atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src); u_int atomic_fetchadd_int(volatile u_int *p, u_int v); u_long atomic_fetchadd_long(volatile u_long *p, u_long v); +int atomic_testandset_int(volatile u_int *p, int v); +int atomic_testandset_long(volatile u_long *p, int v); #define ATOMIC_LOAD(TYPE, LOP) \ u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p) @@ -211,6 +213,42 @@ atomic_fetchadd_long(volatile u_long *p, return (v); } +static __inline int +atomic_testandset_int(volatile u_int *p, int v) +{ + u_char res; + + __asm __volatile( + " " MPLOCKED " " + " btsl %2, %1 ; " + " setc %0 ; " + "# atomic_testandset_int" + : "=r" (res), /* 0 */ + "=m" (*p) /* 1 */ + : "r" (v), /* 2 */ + "m" (*p) /* 3 */ + : "cc"); + return (res); +} + +static __inline int +atomic_testandset_long(volatile u_long *p, int v) +{ + u_char res; + + __asm __volatile( + " " MPLOCKED " " + " btsq %2, %1 ; " + " setc %0 ; " + "# atomic_testandset_long" + : "=r" (res), /* 0 */ + "=m" (*p) /* 1 */ + : "r" ((u_long)v), /* 2 */ + "m" (*p) /* 3 */ + : "cc"); + return (res); +} + /* * We assume that a = b will do atomic loads and stores. Due to the * IA32 memory model, a simple store guarantees release semantics. @@ -435,6 +473,7 @@ u_long atomic_swap_long(volatile u_long #define atomic_swap_32 atomic_swap_int #define atomic_readandclear_32 atomic_readandclear_int #define atomic_fetchadd_32 atomic_fetchadd_int +#define atomic_testandset_32 atomic_testandset_int /* Operations on 64-bit quad words. */ #define atomic_set_64 atomic_set_long @@ -456,6 +495,7 @@ u_long atomic_swap_long(volatile u_long #define atomic_cmpset_rel_64 atomic_cmpset_rel_long #define atomic_swap_64 atomic_swap_long #define atomic_readandclear_64 atomic_readandclear_long +#define atomic_testandset_64 atomic_testandset_long /* Operations on pointers. */ #define atomic_set_ptr atomic_set_long Modified: projects/atomic64/sys/i386/include/atomic.h ============================================================================== --- projects/atomic64/sys/i386/include/atomic.h Thu Aug 1 23:38:57 2013 (r253874) +++ projects/atomic64/sys/i386/include/atomic.h Thu Aug 1 23:51:20 2013 (r253875) @@ -80,6 +80,7 @@ void atomic_##NAME##_barr_##TYPE(volatil int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src); u_int atomic_fetchadd_int(volatile u_int *p, u_int v); +int atomic_testandset_int(volatile u_int *p, int v); #define ATOMIC_LOAD(TYPE, LOP) \ u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p) @@ -282,6 +283,24 @@ atomic_fetchadd_int(volatile u_int *p, u return (v); } +static __inline int +atomic_testandset_int(volatile u_int *p, int v) +{ + u_char res; + + __asm __volatile( + " " MPLOCKED " " + " btsl %2, %1 ; " + " setc %0 ; " + "# atomic_testandset_int" + : "=r" (res), /* 0 (result) */ + "=m" (*p) /* 1 */ + : "r" (v), /* 2 */ + "m" (*p) /* 3 */ + : "cc"); + return (res); +} + /* * We assume that a = b will do atomic loads and stores. Due to the * IA32 memory model, a simple store guarantees release semantics. @@ -394,6 +413,13 @@ atomic_fetchadd_long(volatile u_long *p, return (atomic_fetchadd_int((volatile u_int *)p, (u_int)v)); } +static __inline int +atomic_testandset_long(volatile u_long *p, int v) +{ + + return (atomic_testandset_int((volatile u_int *)p, v)); +} + /* Read the current value and store a new value in the destination. */ #ifdef __GNUCLIKE_ASM @@ -520,6 +546,7 @@ u_long atomic_swap_long(volatile u_long #define atomic_swap_32 atomic_swap_int #define atomic_readandclear_32 atomic_readandclear_int #define atomic_fetchadd_32 atomic_fetchadd_int +#define atomic_testandset_32 atomic_testandset_int /* Operations on pointers. */ #define atomic_set_ptr(p, v) \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308012351.r71NpKxk092536>