atomic.h revision 100327
162587Sitojun/*- 278064Sume * Copyright (c) 1998 Doug Rabson 362587Sitojun * All rights reserved. 4139826Simp * 553541Sshin * Redistribution and use in source and binary forms, with or without 653541Sshin * modification, are permitted provided that the following conditions 753541Sshin * are met: 853541Sshin * 1. Redistributions of source code must retain the above copyright 953541Sshin * notice, this list of conditions and the following disclaimer. 1053541Sshin * 2. Redistributions in binary form must reproduce the above copyright 1153541Sshin * notice, this list of conditions and the following disclaimer in the 1253541Sshin * documentation and/or other materials provided with the distribution. 1353541Sshin * 1453541Sshin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1553541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1653541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1753541Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1853541Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1953541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2053541Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2153541Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2253541Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2353541Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2453541Sshin * SUCH DAMAGE. 2553541Sshin * 2653541Sshin * $FreeBSD: head/sys/amd64/include/atomic.h 100327 2002-07-18 15:56:46Z markm $ 2753541Sshin */ 2853541Sshin#ifndef _MACHINE_ATOMIC_H_ 2953541Sshin#define _MACHINE_ATOMIC_H_ 3053541Sshin 3153541Sshin/* 3253541Sshin * Various simple arithmetic on memory which is atomic in the presence 3362587Sitojun * of interrupts and multiple processors. 3462587Sitojun * 3555009Sshin * atomic_set_char(P, V) (*(u_char*)(P) |= (V)) 36148921Ssuz * atomic_clear_char(P, V) (*(u_char*)(P) &= ~(V)) 3753541Sshin * atomic_add_char(P, V) (*(u_char*)(P) += (V)) 3853541Sshin * atomic_subtract_char(P, V) (*(u_char*)(P) -= (V)) 3953541Sshin * 4078064Sume * atomic_set_short(P, V) (*(u_short*)(P) |= (V)) 4153541Sshin * atomic_clear_short(P, V) (*(u_short*)(P) &= ~(V)) 4253541Sshin * atomic_add_short(P, V) (*(u_short*)(P) += (V)) 4353541Sshin * atomic_subtract_short(P, V) (*(u_short*)(P) -= (V)) 4453541Sshin * 4553541Sshin * atomic_set_int(P, V) (*(u_int*)(P) |= (V)) 4653541Sshin * atomic_clear_int(P, V) (*(u_int*)(P) &= ~(V)) 4778064Sume * atomic_add_int(P, V) (*(u_int*)(P) += (V)) 4853541Sshin * atomic_subtract_int(P, V) (*(u_int*)(P) -= (V)) 4953541Sshin * atomic_readandclear_int(P) (return *(u_int*)P; *(u_int*)P = 0;) 5053541Sshin * 5153541Sshin * atomic_set_long(P, V) (*(u_long*)(P) |= (V)) 5284994Sdarrenr * atomic_clear_long(P, V) (*(u_long*)(P) &= ~(V)) 5353541Sshin * atomic_add_long(P, V) (*(u_long*)(P) += (V)) 5453541Sshin * atomic_subtract_long(P, V) (*(u_long*)(P) -= (V)) 5553541Sshin * atomic_readandclear_long(P) (return *(u_long*)P; *(u_long*)P = 0;) 5678064Sume */ 5778064Sume 5862587Sitojun/* 5978064Sume * The above functions are expanded inline in the statically-linked 6062587Sitojun * kernel. Lock prefixes are generated if an SMP kernel is being 6153541Sshin * built. 62148385Sume * 6362587Sitojun * Kernel modules call real functions which are built into the kernel. 6453541Sshin * This allows kernel modules to be portable between UP and SMP systems. 6553541Sshin */ 6678064Sume#if defined(KLD_MODULE) 6778064Sume#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 6863256Sitojunvoid atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 6953541Sshin 7078064Sumeint atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src); 7162601Sitojun 7278064Sume#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 7353541Sshinu_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 7463256Sitojunvoid atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 7553541Sshin 76105199Ssam#else /* !KLD_MODULE */ 77105199Ssam 78105199Ssam#ifdef __GNUC__ 79105199Ssam 80105199Ssam/* 81105199Ssam * For userland, assume the SMP case and use lock prefixes so that 82105199Ssam * the binaries will run on both types of systems. 8384994Sdarrenr */ 8484994Sdarrenr#if defined(SMP) || !defined(_KERNEL) 8553541Sshin#define MPLOCKED lock ; 8653541Sshin#else 8753541Sshin#define MPLOCKED 8853541Sshin#endif 8953541Sshin 9053541Sshin/* 9153541Sshin * The assembly is volatilized to demark potential before-and-after side 9253541Sshin * effects if an interrupt or SMP collision were to occur. 9353541Sshin */ 9453541Sshin#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 9553541Sshinstatic __inline void \ 9653541Sshinatomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 9753541Sshin{ \ 9853541Sshin __asm __volatile(__XSTRING(MPLOCKED) OP \ 9953541Sshin : "+m" (*p) \ 10053541Sshin : CONS (V)); \ 10153541Sshin} 10253541Sshin 10353541Sshin#else /* !__GNUC__ */ 10453541Sshin 10553541Sshin#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 106122062Sumeextern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 107122062Sume 10853541Sshin#endif /* __GNUC__ */ 10962587Sitojun 11062587Sitojun/* 111148385Sume * Atomic compare and set, used by the mutex functions 112148385Sume * 11363256Sitojun * if (*dst == exp) *dst = src (all 32 bit words) 11453541Sshin * 115122062Sume * Returns 0 on failure, non-zero on success 11653541Sshin */ 117165118Sbz 11853541Sshin#if defined(__GNUC__) 119158295Sbz 120158295Sbz#if defined(I386_CPU) 12163256Sitojun 12253541Sshinstatic __inline int 12353541Sshinatomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) 12453541Sshin{ 12553541Sshin int res = exp; 12653541Sshin 12753541Sshin __asm __volatile( 12853541Sshin " pushfl ; " 12953541Sshin " cli ; " 130105199Ssam " cmpl %0,%2 ; " 13153541Sshin " jne 1f ; " 132105199Ssam " movl %1,%2 ; " 13353541Sshin "1: " 13453541Sshin " sete %%al; " 13553541Sshin " movzbl %%al,%0 ; " 13695023Ssuz " popfl ; " 13753541Sshin "# atomic_cmpset_int" 13878064Sume : "+a" (res) /* 0 (result) */ 13978064Sume : "r" (src), /* 1 */ 14078064Sume "m" (*(dst)) /* 2 */ 14178064Sume : "memory"); 142120913Sume 14378064Sume return (res); 14462587Sitojun} 14578064Sume 14678064Sume#else /* defined(I386_CPU) */ 14753541Sshin 14853541Sshinstatic __inline int 14953541Sshinatomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) 15053541Sshin{ 15153541Sshin int res = exp; 15253541Sshin 15353541Sshin __asm __volatile ( 154165118Sbz " " __XSTRING(MPLOCKED) " " 155165118Sbz " cmpxchgl %1,%2 ; " 15653541Sshin " setz %%al ; " 15753541Sshin " movzbl %%al,%0 ; " 15853541Sshin "1: " 15953541Sshin "# atomic_cmpset_int" 16053541Sshin : "+a" (res) /* 0 (result) */ 16153541Sshin : "r" (src), /* 1 */ 16253541Sshin "m" (*(dst)) /* 2 */ 163148921Ssuz : "memory"); 164148921Ssuz 165148921Ssuz return (res); 16653541Sshin} 16753541Sshin 16853541Sshin#endif /* defined(I386_CPU) */ 16953541Sshin 17053541Sshin#endif /* defined(__GNUC__) */ 17153541Sshin 17253541Sshin#if defined(__GNUC__) 17353541Sshin 174148921Ssuz#if defined(I386_CPU) 175148921Ssuz 176148921Ssuz/* 177148921Ssuz * We assume that a = b will do atomic loads and stores. 17862587Sitojun * 17962587Sitojun * XXX: This is _NOT_ safe on a P6 or higher because it does not guarantee 18062587Sitojun * memory ordering. These should only be used on a 386. 18162587Sitojun */ 18262587Sitojun#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 18362587Sitojunstatic __inline u_##TYPE \ 18462587Sitojunatomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 18562587Sitojun{ \ 18662587Sitojun return (*p); \ 18762587Sitojun} \ 18862587Sitojun \ 18963256Sitojunstatic __inline void \ 19053541Sshinatomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 191120913Sume{ \ 192120913Sume *p = v; \ 19353541Sshin __asm __volatile("" : : : "memory"); \ 19453541Sshin} 19553541Sshin 19662587Sitojun#else /* !defined(I386_CPU) */ 19762587Sitojun 19862587Sitojun#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 19962587Sitojunstatic __inline u_##TYPE \ 20062587Sitojunatomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 20162587Sitojun{ \ 20262587Sitojun u_##TYPE res; \ 20353541Sshin \ 20453541Sshin __asm __volatile(__XSTRING(MPLOCKED) LOP \ 20553541Sshin : "=a" (res), /* 0 (result) */\ 20653541Sshin "+m" (*p) /* 1 */ \ 20753541Sshin : : "memory"); \ 20853541Sshin \ 20953541Sshin return (res); \ 21053541Sshin} \ 21153541Sshin \ 21253541Sshin/* \ 21353541Sshin * The XCHG instruction asserts LOCK automagically. \ 21453541Sshin */ \ 21553541Sshinstatic __inline void \ 21653541Sshinatomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 21753541Sshin{ \ 21862587Sitojun __asm __volatile(SOP \ 21962587Sitojun : "+m" (*p), /* 0 */ \ 22062587Sitojun "+r" (v) /* 1 */ \ 22162587Sitojun : : "memory"); \ 22262587Sitojun} 22362587Sitojun 22462587Sitojun#endif /* defined(I386_CPU) */ 22553541Sshin 22653541Sshin#else /* !defined(__GNUC__) */ 22753541Sshin 22853541Sshinextern int atomic_cmpset_int(volatile u_int *, u_int, u_int); 22953541Sshin 23053541Sshin#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 23153541Sshinextern u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 23253541Sshinextern void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 23362587Sitojun 23453541Sshin#endif /* defined(__GNUC__) */ 23553541Sshin 23653541Sshin#endif /* KLD_MODULE */ 23753541Sshin 23853541SshinATOMIC_ASM(set, char, "orb %b1,%0", "iq", v); 23953541SshinATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v); 24062587SitojunATOMIC_ASM(add, char, "addb %b1,%0", "iq", v); 24162587SitojunATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v); 24262587Sitojun 24362587SitojunATOMIC_ASM(set, short, "orw %w1,%0", "ir", v); 24462587SitojunATOMIC_ASM(clear, short, "andw %w1,%0", "ir", ~v); 24562587SitojunATOMIC_ASM(add, short, "addw %w1,%0", "ir", v); 24662587SitojunATOMIC_ASM(subtract, short, "subw %w1,%0", "ir", v); 24753541Sshin 24853541SshinATOMIC_ASM(set, int, "orl %1,%0", "ir", v); 24953541SshinATOMIC_ASM(clear, int, "andl %1,%0", "ir", ~v); 25053541SshinATOMIC_ASM(add, int, "addl %1,%0", "ir", v); 25153541SshinATOMIC_ASM(subtract, int, "subl %1,%0", "ir", v); 25253541Sshin 25353541SshinATOMIC_ASM(set, long, "orl %1,%0", "ir", v); 25453541SshinATOMIC_ASM(clear, long, "andl %1,%0", "ir", ~v); 25553541SshinATOMIC_ASM(add, long, "addl %1,%0", "ir", v); 25653541SshinATOMIC_ASM(subtract, long, "subl %1,%0", "ir", v); 25753541Sshin 25853541SshinATOMIC_STORE_LOAD(char, "cmpxchgb %b0,%1", "xchgb %b1,%0"); 25953541SshinATOMIC_STORE_LOAD(short,"cmpxchgw %w0,%1", "xchgw %w1,%0"); 26053541SshinATOMIC_STORE_LOAD(int, "cmpxchgl %0,%1", "xchgl %1,%0"); 26153541SshinATOMIC_STORE_LOAD(long, "cmpxchgl %0,%1", "xchgl %1,%0"); 262122062Sume 26353541Sshin#undef ATOMIC_ASM 26453541Sshin#undef ATOMIC_STORE_LOAD 26553541Sshin 266122062Sume#define atomic_set_acq_char atomic_set_char 267122062Sume#define atomic_set_rel_char atomic_set_char 268122062Sume#define atomic_clear_acq_char atomic_clear_char 269122062Sume#define atomic_clear_rel_char atomic_clear_char 270122062Sume#define atomic_add_acq_char atomic_add_char 271122062Sume#define atomic_add_rel_char atomic_add_char 272122062Sume#define atomic_subtract_acq_char atomic_subtract_char 273122062Sume#define atomic_subtract_rel_char atomic_subtract_char 274122062Sume 275126006Sume#define atomic_set_acq_short atomic_set_short 276126006Sume#define atomic_set_rel_short atomic_set_short 277126006Sume#define atomic_clear_acq_short atomic_clear_short 278126006Sume#define atomic_clear_rel_short atomic_clear_short 279122062Sume#define atomic_add_acq_short atomic_add_short 280122062Sume#define atomic_add_rel_short atomic_add_short 281122062Sume#define atomic_subtract_acq_short atomic_subtract_short 282126006Sume#define atomic_subtract_rel_short atomic_subtract_short 283126006Sume 284126006Sume#define atomic_set_acq_int atomic_set_int 285126006Sume#define atomic_set_rel_int atomic_set_int 286126006Sume#define atomic_clear_acq_int atomic_clear_int 287126006Sume#define atomic_clear_rel_int atomic_clear_int 288126006Sume#define atomic_add_acq_int atomic_add_int 28953541Sshin#define atomic_add_rel_int atomic_add_int 29053541Sshin#define atomic_subtract_acq_int atomic_subtract_int 29153541Sshin#define atomic_subtract_rel_int atomic_subtract_int 29253541Sshin#define atomic_cmpset_acq_int atomic_cmpset_int 29353541Sshin#define atomic_cmpset_rel_int atomic_cmpset_int 29453541Sshin 29553541Sshin#define atomic_set_acq_long atomic_set_long 29653541Sshin#define atomic_set_rel_long atomic_set_long 29753541Sshin#define atomic_clear_acq_long atomic_clear_long 29853541Sshin#define atomic_clear_rel_long atomic_clear_long 29953541Sshin#define atomic_add_acq_long atomic_add_long 30053541Sshin#define atomic_add_rel_long atomic_add_long 30153541Sshin#define atomic_subtract_acq_long atomic_subtract_long 30253541Sshin#define atomic_subtract_rel_long atomic_subtract_long 30353541Sshin#define atomic_cmpset_long atomic_cmpset_int 30453541Sshin#define atomic_cmpset_acq_long atomic_cmpset_acq_int 30553541Sshin#define atomic_cmpset_rel_long atomic_cmpset_rel_int 30653541Sshin 30753541Sshin#define atomic_cmpset_acq_ptr atomic_cmpset_ptr 30853541Sshin#define atomic_cmpset_rel_ptr atomic_cmpset_ptr 30953541Sshin 31053541Sshin#define atomic_set_8 atomic_set_char 31153541Sshin#define atomic_set_acq_8 atomic_set_acq_char 31253541Sshin#define atomic_set_rel_8 atomic_set_rel_char 31353541Sshin#define atomic_clear_8 atomic_clear_char 31453541Sshin#define atomic_clear_acq_8 atomic_clear_acq_char 31553541Sshin#define atomic_clear_rel_8 atomic_clear_rel_char 31653541Sshin#define atomic_add_8 atomic_add_char 317120913Sume#define atomic_add_acq_8 atomic_add_acq_char 31853541Sshin#define atomic_add_rel_8 atomic_add_rel_char 31953541Sshin#define atomic_subtract_8 atomic_subtract_char 32053541Sshin#define atomic_subtract_acq_8 atomic_subtract_acq_char 32153541Sshin#define atomic_subtract_rel_8 atomic_subtract_rel_char 32253541Sshin#define atomic_load_acq_8 atomic_load_acq_char 32362587Sitojun#define atomic_store_rel_8 atomic_store_rel_char 32462587Sitojun 32562587Sitojun#define atomic_set_16 atomic_set_short 32662587Sitojun#define atomic_set_acq_16 atomic_set_acq_short 32762587Sitojun#define atomic_set_rel_16 atomic_set_rel_short 32862587Sitojun#define atomic_clear_16 atomic_clear_short 32962587Sitojun#define atomic_clear_acq_16 atomic_clear_acq_short 33053541Sshin#define atomic_clear_rel_16 atomic_clear_rel_short 33153541Sshin#define atomic_add_16 atomic_add_short 33253541Sshin#define atomic_add_acq_16 atomic_add_acq_short 333122062Sume#define atomic_add_rel_16 atomic_add_rel_short 334126006Sume#define atomic_subtract_16 atomic_subtract_short 335126006Sume#define atomic_subtract_acq_16 atomic_subtract_acq_short 336126006Sume#define atomic_subtract_rel_16 atomic_subtract_rel_short 337126006Sume#define atomic_load_acq_16 atomic_load_acq_short 338126006Sume#define atomic_store_rel_16 atomic_store_rel_short 339126006Sume 340126006Sume#define atomic_set_32 atomic_set_int 341126006Sume#define atomic_set_acq_32 atomic_set_acq_int 342126006Sume#define atomic_set_rel_32 atomic_set_rel_int 343126006Sume#define atomic_clear_32 atomic_clear_int 344122062Sume#define atomic_clear_acq_32 atomic_clear_acq_int 345122062Sume#define atomic_clear_rel_32 atomic_clear_rel_int 346122062Sume#define atomic_add_32 atomic_add_int 347122062Sume#define atomic_add_acq_32 atomic_add_acq_int 348122062Sume#define atomic_add_rel_32 atomic_add_rel_int 34953541Sshin#define atomic_subtract_32 atomic_subtract_int 35053541Sshin#define atomic_subtract_acq_32 atomic_subtract_acq_int 35163256Sitojun#define atomic_subtract_rel_32 atomic_subtract_rel_int 35253541Sshin#define atomic_load_acq_32 atomic_load_acq_int 353122062Sume#define atomic_store_rel_32 atomic_store_rel_int 354122062Sume#define atomic_cmpset_32 atomic_cmpset_int 355122062Sume#define atomic_cmpset_acq_32 atomic_cmpset_acq_int 356122062Sume#define atomic_cmpset_rel_32 atomic_cmpset_rel_int 357122062Sume#define atomic_readandclear_32 atomic_readandclear_int 35878064Sume 35953541Sshin#if !defined(WANT_FUNCTIONS) 360120913Sumestatic __inline int 36153541Sshinatomic_cmpset_ptr(volatile void *dst, void *exp, void *src) 36253541Sshin{ 36353541Sshin 36453541Sshin return (atomic_cmpset_int((volatile u_int *)dst, (u_int)exp, 36553541Sshin (u_int)src)); 36653541Sshin} 367120913Sume 36853541Sshinstatic __inline void * 369122921Sandreatomic_load_acq_ptr(volatile void *p) 37053541Sshin{ 37162587Sitojun return (void *)atomic_load_acq_int((volatile u_int *)p); 37253541Sshin} 37353541Sshin 37478064Sumestatic __inline void 37562587Sitojunatomic_store_rel_ptr(volatile void *p, void *v) 37662587Sitojun{ 37762587Sitojun atomic_store_rel_int((volatile u_int *)p, (u_int)v); 37862587Sitojun} 37962587Sitojun 38053541Sshin#define ATOMIC_PTR(NAME) \ 38153541Sshinstatic __inline void \ 38253541Sshinatomic_##NAME##_ptr(volatile void *p, uintptr_t v) \ 383120913Sume{ \ 38453541Sshin atomic_##NAME##_int((volatile u_int *)p, v); \ 38553541Sshin} \ 38653541Sshin \ 38753541Sshinstatic __inline void \ 38853541Sshinatomic_##NAME##_acq_ptr(volatile void *p, uintptr_t v) \ 38953541Sshin{ \ 39053541Sshin atomic_##NAME##_acq_int((volatile u_int *)p, v);\ 39153541Sshin} \ 39253541Sshin \ 393122921Sandrestatic __inline void \ 39453541Sshinatomic_##NAME##_rel_ptr(volatile void *p, uintptr_t v) \ 39553541Sshin{ \ 39678064Sume atomic_##NAME##_rel_int((volatile u_int *)p, v);\ 39762587Sitojun} 39862587Sitojun 39962587SitojunATOMIC_PTR(set) 40062587SitojunATOMIC_PTR(clear) 40162587SitojunATOMIC_PTR(add) 40253541SshinATOMIC_PTR(subtract) 40353541Sshin 40453541Sshin#undef ATOMIC_PTR 40553541Sshin 406122062Sume#if defined(__GNUC__) 407122062Sume 408122062Sumestatic __inline u_int 40962587Sitojunatomic_readandclear_int(volatile u_int *addr) 41062587Sitojun{ 411148385Sume u_int result; 412148385Sume 413148385Sume __asm __volatile ( 414148385Sume " xorl %0,%0 ; " 415148385Sume " xchgl %1,%0 ; " 416148385Sume "# atomic_readandclear_int" 417148385Sume : "=&r" (result) /* 0 (result) */ 41862587Sitojun : "m" (*addr)); /* 1 (addr) */ 419148385Sume 420148385Sume return (result); 421122062Sume} 42262587Sitojun 42362587Sitojunstatic __inline u_long 424122062Sumeatomic_readandclear_long(volatile u_long *addr) 425122062Sume{ 426122062Sume u_long result; 427148385Sume 428148385Sume __asm __volatile ( 429148385Sume " xorl %0,%0 ; " 430148385Sume " xchgl %1,%0 ; " 431148385Sume "# atomic_readandclear_int" 432148385Sume : "=&r" (result) /* 0 (result) */ 433148385Sume : "m" (*addr)); /* 1 (addr) */ 434122062Sume 435122062Sume return (result); 436122062Sume} 437122062Sume 438122062Sume#else /* !defined(__GNUC__) */ 439122062Sume 44062587Sitojunextern u_long atomic_readandclear_long(volatile u_long *); 44162587Sitojunextern u_int atomic_readandclear_int(volatile u_int *); 44262587Sitojun 44362587Sitojun#endif /* defined(__GNUC__) */ 44462587Sitojun 44562587Sitojun#endif /* !defined(WANT_FUNCTIONS) */ 44662587Sitojun#endif /* ! _MACHINE_ATOMIC_H_ */ 447165118Sbz