atomic.h revision 165633
138517Sdfr/*- 238517Sdfr * Copyright (c) 1998 Doug Rabson 338517Sdfr * All rights reserved. 438517Sdfr * 538517Sdfr * Redistribution and use in source and binary forms, with or without 638517Sdfr * modification, are permitted provided that the following conditions 738517Sdfr * are met: 838517Sdfr * 1. Redistributions of source code must retain the above copyright 938517Sdfr * notice, this list of conditions and the following disclaimer. 1038517Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1138517Sdfr * notice, this list of conditions and the following disclaimer in the 1238517Sdfr * documentation and/or other materials provided with the distribution. 1338517Sdfr * 1438517Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1538517Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1638517Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1738517Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1838517Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1938517Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2038517Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2138517Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2238517Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2338517Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2438517Sdfr * SUCH DAMAGE. 2538517Sdfr * 2650477Speter * $FreeBSD: head/sys/amd64/include/atomic.h 165633 2006-12-29 14:28:23Z bde $ 2738517Sdfr */ 2838517Sdfr#ifndef _MACHINE_ATOMIC_H_ 29147855Sjhb#define _MACHINE_ATOMIC_H_ 3038517Sdfr 31143063Sjoerg#ifndef _SYS_CDEFS_H_ 32143063Sjoerg#error this file needs sys/cdefs.h as a prerequisite 33143063Sjoerg#endif 34143063Sjoerg 3538517Sdfr/* 3638517Sdfr * Various simple arithmetic on memory which is atomic in the presence 3748797Salc * of interrupts and multiple processors. 3838517Sdfr * 39165633Sbde * atomic_set_char(P, V) (*(u_char *)(P) |= (V)) 40165633Sbde * atomic_clear_char(P, V) (*(u_char *)(P) &= ~(V)) 41165633Sbde * atomic_add_char(P, V) (*(u_char *)(P) += (V)) 42165633Sbde * atomic_subtract_char(P, V) (*(u_char *)(P) -= (V)) 4348797Salc * 44165633Sbde * atomic_set_short(P, V) (*(u_short *)(P) |= (V)) 45165633Sbde * atomic_clear_short(P, V) (*(u_short *)(P) &= ~(V)) 46165633Sbde * atomic_add_short(P, V) (*(u_short *)(P) += (V)) 47165633Sbde * atomic_subtract_short(P, V) (*(u_short *)(P) -= (V)) 4848797Salc * 49165633Sbde * atomic_set_int(P, V) (*(u_int *)(P) |= (V)) 50165633Sbde * atomic_clear_int(P, V) (*(u_int *)(P) &= ~(V)) 51165633Sbde * atomic_add_int(P, V) (*(u_int *)(P) += (V)) 52165633Sbde * atomic_subtract_int(P, V) (*(u_int *)(P) -= (V)) 53165633Sbde * atomic_readandclear_int(P) (return *(u_int *)P; *(u_int *)P = 0;) 5448797Salc * 55165633Sbde * atomic_set_long(P, V) (*(u_long *)(P) |= (V)) 56165633Sbde * atomic_clear_long(P, V) (*(u_long *)(P) &= ~(V)) 57165633Sbde * atomic_add_long(P, V) (*(u_long *)(P) += (V)) 58165633Sbde * atomic_subtract_long(P, V) (*(u_long *)(P) -= (V)) 59165633Sbde * atomic_readandclear_long(P) (return *(u_long *)P; *(u_long *)P = 0;) 6038517Sdfr */ 6138517Sdfr 6248797Salc/* 6349999Salc * The above functions are expanded inline in the statically-linked 6449999Salc * kernel. Lock prefixes are generated if an SMP kernel is being 6549999Salc * built. 6649999Salc * 6749999Salc * Kernel modules call real functions which are built into the kernel. 6849999Salc * This allows kernel modules to be portable between UP and SMP systems. 6948797Salc */ 70165578Sbde#if defined(KLD_MODULE) || !defined(__GNUCLIKE_ASM) 71147855Sjhb#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 72100251Smarkmvoid atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 7349999Salc 74165633Sbdeint atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src); 75165633Sbdeint atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src); 76165633Sbdeu_int atomic_fetchadd_int(volatile u_int *p, u_int v); 7765514Sphk 7871085Sjhb#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 7971085Sjhbu_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 80100251Smarkmvoid atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 8171085Sjhb 82165578Sbde#else /* !KLD_MODULE && __GNUCLIKE_ASM */ 8372358Smarkm 8484679Sjhb/* 8584679Sjhb * For userland, assume the SMP case and use lock prefixes so that 8684679Sjhb * the binaries will run on both types of systems. 8784679Sjhb */ 88122849Speter#if defined(SMP) || !defined(_KERNEL) 89165630Sbde#define MPLOCKED "lock ; " 9090515Sbde#else 91147855Sjhb#define MPLOCKED 9290515Sbde#endif 9338517Sdfr 9448797Salc/* 9548797Salc * The assembly is volatilized to demark potential before-and-after side 9648797Salc * effects if an interrupt or SMP collision were to occur. 9748797Salc */ 98147855Sjhb#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 9948797Salcstatic __inline void \ 10049043Salcatomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 10148797Salc{ \ 102165630Sbde __asm __volatile(MPLOCKED OP \ 103165633Sbde : "=m" (*p) \ 104165633Sbde : CONS (V), "m" (*p)); \ 105122940Speter} \ 106122940Speterstruct __hack 107100327Smarkm 10865514Sphk/* 10965514Sphk * Atomic compare and set, used by the mutex functions 11065514Sphk * 11165514Sphk * if (*dst == exp) *dst = src (all 32 bit words) 11265514Sphk * 11365514Sphk * Returns 0 on failure, non-zero on success 11465514Sphk */ 11565514Sphk 11665514Sphkstatic __inline int 11765514Sphkatomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) 11865514Sphk{ 119165572Sbde u_char res; 12065514Sphk 121165633Sbde __asm __volatile( 122165630Sbde " " MPLOCKED " " 123150182Sjhb " cmpxchgl %2,%1 ; " 124165572Sbde " sete %0 ; " 12565514Sphk "1: " 12665514Sphk "# atomic_cmpset_int" 127165572Sbde : "=a" (res), /* 0 */ 128150182Sjhb "=m" (*dst) /* 1 */ 129150182Sjhb : "r" (src), /* 2 */ 130165572Sbde "a" (exp), /* 3 */ 131165572Sbde "m" (*dst) /* 4 */ 132150182Sjhb : "memory"); 13365514Sphk 13465514Sphk return (res); 13565514Sphk} 136100327Smarkm 13765514Sphkstatic __inline int 138114349Speteratomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) 13965514Sphk{ 140165572Sbde u_char res; 14165514Sphk 142165633Sbde __asm __volatile( 143165630Sbde " " MPLOCKED " " 144150182Sjhb " cmpxchgq %2,%1 ; " 145165572Sbde " sete %0 ; " 14665514Sphk "1: " 147114349Speter "# atomic_cmpset_long" 148165572Sbde : "=a" (res), /* 0 */ 149150182Sjhb "=m" (*dst) /* 1 */ 150150182Sjhb : "r" (src), /* 2 */ 151165572Sbde "a" (exp), /* 3 */ 152165572Sbde "m" (*dst) /* 4 */ 153150182Sjhb : "memory"); 15465514Sphk 15565514Sphk return (res); 15665514Sphk} 15765514Sphk 158150627Sjhb/* 159150627Sjhb * Atomically add the value of v to the integer pointed to by p and return 160150627Sjhb * the previous value of *p. 161150627Sjhb */ 162150627Sjhbstatic __inline u_int 163150627Sjhbatomic_fetchadd_int(volatile u_int *p, u_int v) 164150627Sjhb{ 165150627Sjhb 166165633Sbde __asm __volatile( 167165630Sbde " " MPLOCKED " " 168150627Sjhb " xaddl %0, %1 ; " 169150627Sjhb "# atomic_fetchadd_int" 170150627Sjhb : "+r" (v), /* 0 (result) */ 171150627Sjhb "=m" (*p) /* 1 */ 172150627Sjhb : "m" (*p)); /* 2 */ 173150627Sjhb 174150627Sjhb return (v); 175150627Sjhb} 176150627Sjhb 177148267Speter#if defined(_KERNEL) && !defined(SMP) 178148267Speter 179148267Speter/* 180148267Speter * We assume that a = b will do atomic loads and stores. However, on a 181148267Speter * PentiumPro or higher, reads may pass writes, so for that case we have 182148267Speter * to use a serializing instruction (i.e. with LOCK) to do the load in 183148267Speter * SMP kernels. For UP kernels, however, the cache of the single processor 184148267Speter * is always consistent, so we don't need any memory barriers. 185148267Speter */ 186147855Sjhb#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 18767351Sjhbstatic __inline u_##TYPE \ 18867351Sjhbatomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 18967351Sjhb{ \ 190148267Speter return (*p); \ 191148267Speter} \ 192148267Speter \ 193148267Speterstatic __inline void \ 194148267Speteratomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 195148267Speter{ \ 196148267Speter *p = v; \ 197148267Speter} \ 198148267Speterstruct __hack 199148267Speter 200148267Speter#else /* defined(SMP) */ 201148267Speter 202148267Speter#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 203148267Speterstatic __inline u_##TYPE \ 204148267Speteratomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 205148267Speter{ \ 20671023Sjhb u_##TYPE res; \ 20771023Sjhb \ 208165630Sbde __asm __volatile(MPLOCKED LOP \ 20971141Sjhb : "=a" (res), /* 0 (result) */\ 210150182Sjhb "=m" (*p) /* 1 */ \ 211150182Sjhb : "m" (*p) /* 2 */ \ 212165578Sbde : "memory"); \ 21371023Sjhb \ 21471023Sjhb return (res); \ 21571023Sjhb} \ 21671023Sjhb \ 21771023Sjhb/* \ 21871023Sjhb * The XCHG instruction asserts LOCK automagically. \ 21971023Sjhb */ \ 22071023Sjhbstatic __inline void \ 22171023Sjhbatomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 22271023Sjhb{ \ 22371023Sjhb __asm __volatile(SOP \ 224150182Sjhb : "=m" (*p), /* 0 */ \ 22571023Sjhb "+r" (v) /* 1 */ \ 226150182Sjhb : "m" (*p)); /* 2 */ \ 227122940Speter} \ 228122940Speterstruct __hack 229100327Smarkm 230148267Speter#endif /* SMP */ 231148267Speter 232165578Sbde#endif /* KLD_MODULE || !__GNUCLIKE_ASM */ 233100251Smarkm 234100251SmarkmATOMIC_ASM(set, char, "orb %b1,%0", "iq", v); 235100251SmarkmATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v); 236100251SmarkmATOMIC_ASM(add, char, "addb %b1,%0", "iq", v); 237100251SmarkmATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v); 23871085Sjhb 239100251SmarkmATOMIC_ASM(set, short, "orw %w1,%0", "ir", v); 240100251SmarkmATOMIC_ASM(clear, short, "andw %w1,%0", "ir", ~v); 241100251SmarkmATOMIC_ASM(add, short, "addw %w1,%0", "ir", v); 242100251SmarkmATOMIC_ASM(subtract, short, "subw %w1,%0", "ir", v); 24371085Sjhb 244100251SmarkmATOMIC_ASM(set, int, "orl %1,%0", "ir", v); 245100251SmarkmATOMIC_ASM(clear, int, "andl %1,%0", "ir", ~v); 246100251SmarkmATOMIC_ASM(add, int, "addl %1,%0", "ir", v); 247100251SmarkmATOMIC_ASM(subtract, int, "subl %1,%0", "ir", v); 24871085Sjhb 249114349SpeterATOMIC_ASM(set, long, "orq %1,%0", "ir", v); 250114349SpeterATOMIC_ASM(clear, long, "andq %1,%0", "ir", ~v); 251114349SpeterATOMIC_ASM(add, long, "addq %1,%0", "ir", v); 252114349SpeterATOMIC_ASM(subtract, long, "subq %1,%0", "ir", v); 25371085Sjhb 254100251SmarkmATOMIC_STORE_LOAD(char, "cmpxchgb %b0,%1", "xchgb %b1,%0"); 255100251SmarkmATOMIC_STORE_LOAD(short,"cmpxchgw %w0,%1", "xchgw %w1,%0"); 256100251SmarkmATOMIC_STORE_LOAD(int, "cmpxchgl %0,%1", "xchgl %1,%0"); 257114349SpeterATOMIC_STORE_LOAD(long, "cmpxchgq %0,%1", "xchgq %1,%0"); 25871023Sjhb 25971085Sjhb#undef ATOMIC_ASM 26067351Sjhb#undef ATOMIC_STORE_LOAD 26167351Sjhb 262147855Sjhb#if !defined(WANT_FUNCTIONS) 263147855Sjhb 264147855Sjhb/* Read the current value and store a zero in the destination. */ 265165578Sbde#ifdef __GNUCLIKE_ASM 266147855Sjhb 267147855Sjhbstatic __inline u_int 268147855Sjhbatomic_readandclear_int(volatile u_int *addr) 269147855Sjhb{ 270147855Sjhb u_int result; 271147855Sjhb 272150182Sjhb result = 0; 273165633Sbde __asm __volatile( 274147855Sjhb " xchgl %1,%0 ; " 275147855Sjhb "# atomic_readandclear_int" 276150182Sjhb : "+r" (result), /* 0 (result) */ 277150182Sjhb "=m" (*addr) /* 1 (addr) */ 278150182Sjhb : "m" (*addr)); 279147855Sjhb 280147855Sjhb return (result); 281147855Sjhb} 282147855Sjhb 283147855Sjhbstatic __inline u_long 284147855Sjhbatomic_readandclear_long(volatile u_long *addr) 285147855Sjhb{ 286147855Sjhb u_long result; 287147855Sjhb 288150182Sjhb result = 0; 289165633Sbde __asm __volatile( 290147855Sjhb " xchgq %1,%0 ; " 291147855Sjhb "# atomic_readandclear_long" 292150182Sjhb : "+r" (result), /* 0 (result) */ 293150182Sjhb "=m" (*addr) /* 1 (addr) */ 294150182Sjhb : "m" (*addr)); 295147855Sjhb 296147855Sjhb return (result); 297147855Sjhb} 298147855Sjhb 299165578Sbde#else /* !__GNUCLIKE_ASM */ 300147855Sjhb 301147855Sjhbu_int atomic_readandclear_int(volatile u_int *); 302147855Sjhbu_long atomic_readandclear_long(volatile u_long *); 303147855Sjhb 304165578Sbde#endif /* __GNUCLIKE_ASM */ 305147855Sjhb 306147855Sjhb/* Acquire and release variants are identical to the normal ones. */ 30771085Sjhb#define atomic_set_acq_char atomic_set_char 30871085Sjhb#define atomic_set_rel_char atomic_set_char 30971085Sjhb#define atomic_clear_acq_char atomic_clear_char 31071085Sjhb#define atomic_clear_rel_char atomic_clear_char 31171085Sjhb#define atomic_add_acq_char atomic_add_char 31271085Sjhb#define atomic_add_rel_char atomic_add_char 31371085Sjhb#define atomic_subtract_acq_char atomic_subtract_char 31471085Sjhb#define atomic_subtract_rel_char atomic_subtract_char 31571085Sjhb 31671085Sjhb#define atomic_set_acq_short atomic_set_short 31771085Sjhb#define atomic_set_rel_short atomic_set_short 31871085Sjhb#define atomic_clear_acq_short atomic_clear_short 31971085Sjhb#define atomic_clear_rel_short atomic_clear_short 32071085Sjhb#define atomic_add_acq_short atomic_add_short 32171085Sjhb#define atomic_add_rel_short atomic_add_short 32271085Sjhb#define atomic_subtract_acq_short atomic_subtract_short 32371085Sjhb#define atomic_subtract_rel_short atomic_subtract_short 32471085Sjhb 32571085Sjhb#define atomic_set_acq_int atomic_set_int 32671085Sjhb#define atomic_set_rel_int atomic_set_int 32771085Sjhb#define atomic_clear_acq_int atomic_clear_int 32871085Sjhb#define atomic_clear_rel_int atomic_clear_int 32971085Sjhb#define atomic_add_acq_int atomic_add_int 33071085Sjhb#define atomic_add_rel_int atomic_add_int 33171085Sjhb#define atomic_subtract_acq_int atomic_subtract_int 33271085Sjhb#define atomic_subtract_rel_int atomic_subtract_int 333147855Sjhb#define atomic_cmpset_acq_int atomic_cmpset_int 334147855Sjhb#define atomic_cmpset_rel_int atomic_cmpset_int 33571085Sjhb 33671085Sjhb#define atomic_set_acq_long atomic_set_long 33771085Sjhb#define atomic_set_rel_long atomic_set_long 33871085Sjhb#define atomic_clear_acq_long atomic_clear_long 33971085Sjhb#define atomic_clear_rel_long atomic_clear_long 34071085Sjhb#define atomic_add_acq_long atomic_add_long 34171085Sjhb#define atomic_add_rel_long atomic_add_long 34271085Sjhb#define atomic_subtract_acq_long atomic_subtract_long 34371085Sjhb#define atomic_subtract_rel_long atomic_subtract_long 344147855Sjhb#define atomic_cmpset_acq_long atomic_cmpset_long 345147855Sjhb#define atomic_cmpset_rel_long atomic_cmpset_long 34671085Sjhb 347147855Sjhb/* Operations on 8-bit bytes. */ 34871085Sjhb#define atomic_set_8 atomic_set_char 34971085Sjhb#define atomic_set_acq_8 atomic_set_acq_char 35071085Sjhb#define atomic_set_rel_8 atomic_set_rel_char 35171085Sjhb#define atomic_clear_8 atomic_clear_char 35271085Sjhb#define atomic_clear_acq_8 atomic_clear_acq_char 35371085Sjhb#define atomic_clear_rel_8 atomic_clear_rel_char 35471085Sjhb#define atomic_add_8 atomic_add_char 35571085Sjhb#define atomic_add_acq_8 atomic_add_acq_char 35671085Sjhb#define atomic_add_rel_8 atomic_add_rel_char 35771085Sjhb#define atomic_subtract_8 atomic_subtract_char 35871085Sjhb#define atomic_subtract_acq_8 atomic_subtract_acq_char 35971085Sjhb#define atomic_subtract_rel_8 atomic_subtract_rel_char 36071085Sjhb#define atomic_load_acq_8 atomic_load_acq_char 36171085Sjhb#define atomic_store_rel_8 atomic_store_rel_char 36271085Sjhb 363147855Sjhb/* Operations on 16-bit words. */ 36471085Sjhb#define atomic_set_16 atomic_set_short 36571085Sjhb#define atomic_set_acq_16 atomic_set_acq_short 36671085Sjhb#define atomic_set_rel_16 atomic_set_rel_short 36771085Sjhb#define atomic_clear_16 atomic_clear_short 36871085Sjhb#define atomic_clear_acq_16 atomic_clear_acq_short 36971085Sjhb#define atomic_clear_rel_16 atomic_clear_rel_short 37071085Sjhb#define atomic_add_16 atomic_add_short 37171085Sjhb#define atomic_add_acq_16 atomic_add_acq_short 37271085Sjhb#define atomic_add_rel_16 atomic_add_rel_short 37371085Sjhb#define atomic_subtract_16 atomic_subtract_short 37471085Sjhb#define atomic_subtract_acq_16 atomic_subtract_acq_short 37571085Sjhb#define atomic_subtract_rel_16 atomic_subtract_rel_short 37671085Sjhb#define atomic_load_acq_16 atomic_load_acq_short 37771085Sjhb#define atomic_store_rel_16 atomic_store_rel_short 37871085Sjhb 379147855Sjhb/* Operations on 32-bit double words. */ 38071085Sjhb#define atomic_set_32 atomic_set_int 38171085Sjhb#define atomic_set_acq_32 atomic_set_acq_int 38271085Sjhb#define atomic_set_rel_32 atomic_set_rel_int 38371085Sjhb#define atomic_clear_32 atomic_clear_int 38471085Sjhb#define atomic_clear_acq_32 atomic_clear_acq_int 38571085Sjhb#define atomic_clear_rel_32 atomic_clear_rel_int 38671085Sjhb#define atomic_add_32 atomic_add_int 38771085Sjhb#define atomic_add_acq_32 atomic_add_acq_int 38871085Sjhb#define atomic_add_rel_32 atomic_add_rel_int 38971085Sjhb#define atomic_subtract_32 atomic_subtract_int 39071085Sjhb#define atomic_subtract_acq_32 atomic_subtract_acq_int 39171085Sjhb#define atomic_subtract_rel_32 atomic_subtract_rel_int 39271085Sjhb#define atomic_load_acq_32 atomic_load_acq_int 39371085Sjhb#define atomic_store_rel_32 atomic_store_rel_int 39471085Sjhb#define atomic_cmpset_32 atomic_cmpset_int 39571085Sjhb#define atomic_cmpset_acq_32 atomic_cmpset_acq_int 39671085Sjhb#define atomic_cmpset_rel_32 atomic_cmpset_rel_int 39771085Sjhb#define atomic_readandclear_32 atomic_readandclear_int 398150627Sjhb#define atomic_fetchadd_32 atomic_fetchadd_int 39971085Sjhb 400149233Sjhb/* Operations on 64-bit quad words. */ 401149233Sjhb#define atomic_set_64 atomic_set_long 402149233Sjhb#define atomic_set_acq_64 atomic_set_acq_long 403149233Sjhb#define atomic_set_rel_64 atomic_set_rel_long 404149233Sjhb#define atomic_clear_64 atomic_clear_long 405149233Sjhb#define atomic_clear_acq_64 atomic_clear_acq_long 406149233Sjhb#define atomic_clear_rel_64 atomic_clear_rel_long 407149233Sjhb#define atomic_add_64 atomic_add_long 408149233Sjhb#define atomic_add_acq_64 atomic_add_acq_long 409149233Sjhb#define atomic_add_rel_64 atomic_add_rel_long 410149233Sjhb#define atomic_subtract_64 atomic_subtract_long 411149233Sjhb#define atomic_subtract_acq_64 atomic_subtract_acq_long 412149233Sjhb#define atomic_subtract_rel_64 atomic_subtract_rel_long 413149233Sjhb#define atomic_load_acq_64 atomic_load_acq_long 414149233Sjhb#define atomic_store_rel_64 atomic_store_rel_long 415149233Sjhb#define atomic_cmpset_64 atomic_cmpset_long 416149233Sjhb#define atomic_cmpset_acq_64 atomic_cmpset_acq_long 417149233Sjhb#define atomic_cmpset_rel_64 atomic_cmpset_rel_long 418149233Sjhb#define atomic_readandclear_64 atomic_readandclear_long 419149233Sjhb 420147855Sjhb/* Operations on pointers. */ 421148067Sjhb#define atomic_set_ptr atomic_set_long 422148067Sjhb#define atomic_set_acq_ptr atomic_set_acq_long 423148067Sjhb#define atomic_set_rel_ptr atomic_set_rel_long 424148067Sjhb#define atomic_clear_ptr atomic_clear_long 425148067Sjhb#define atomic_clear_acq_ptr atomic_clear_acq_long 426148067Sjhb#define atomic_clear_rel_ptr atomic_clear_rel_long 427148067Sjhb#define atomic_add_ptr atomic_add_long 428148067Sjhb#define atomic_add_acq_ptr atomic_add_acq_long 429148067Sjhb#define atomic_add_rel_ptr atomic_add_rel_long 430148067Sjhb#define atomic_subtract_ptr atomic_subtract_long 431148067Sjhb#define atomic_subtract_acq_ptr atomic_subtract_acq_long 432148067Sjhb#define atomic_subtract_rel_ptr atomic_subtract_rel_long 433148067Sjhb#define atomic_load_acq_ptr atomic_load_acq_long 434148067Sjhb#define atomic_store_rel_ptr atomic_store_rel_long 435148067Sjhb#define atomic_cmpset_ptr atomic_cmpset_long 436148067Sjhb#define atomic_cmpset_acq_ptr atomic_cmpset_acq_long 437148067Sjhb#define atomic_cmpset_rel_ptr atomic_cmpset_rel_long 438148067Sjhb#define atomic_readandclear_ptr atomic_readandclear_long 43965514Sphk 440165633Sbde#endif /* !defined(WANT_FUNCTIONS) */ 441165633Sbde 442165633Sbde#endif /* !_MACHINE_ATOMIC_H_ */ 443