atomic.h revision 165635
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/i386/include/atomic.h 165635 2006-12-29 15:29:49Z 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/* 36165635Sbde * Various simple operations on memory, each of which is atomic in the 37165635Sbde * presence 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)) 53165635Sbde * 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)) 59165635Sbde * 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 */ 70147855Sjhb#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); 75165633Sbdeu_int atomic_fetchadd_int(volatile u_int *p, u_int v); 7665514Sphk 7771085Sjhb#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 7871085Sjhbu_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 79100251Smarkmvoid atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 8071085Sjhb 81147855Sjhb#else /* !KLD_MODULE && __GNUCLIKE_ASM */ 8272358Smarkm 8384679Sjhb/* 84165635Sbde * For userland, always use lock prefixes so that the binaries will run 85165635Sbde * on both SMP and !SMP systems. 8684679Sjhb */ 8784679Sjhb#if defined(SMP) || !defined(_KERNEL) 88165630Sbde#define MPLOCKED "lock ; " 8990515Sbde#else 90147855Sjhb#define MPLOCKED 9190515Sbde#endif 9238517Sdfr 9348797Salc/* 9448797Salc * The assembly is volatilized to demark potential before-and-after side 9548797Salc * effects if an interrupt or SMP collision were to occur. 9648797Salc */ 97147855Sjhb#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 9848797Salcstatic __inline void \ 9949043Salcatomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 10048797Salc{ \ 101165630Sbde __asm __volatile(MPLOCKED OP \ 102165633Sbde : "=m" (*p) \ 103165633Sbde : CONS (V), "m" (*p)); \ 104122827Sbde} \ 105122827Sbdestruct __hack 106100327Smarkm 10765514Sphk/* 10865514Sphk * Atomic compare and set, used by the mutex functions 10965514Sphk * 11065514Sphk * if (*dst == exp) *dst = src (all 32 bit words) 11165514Sphk * 11265514Sphk * Returns 0 on failure, non-zero on success 11365514Sphk */ 11465514Sphk 115165635Sbde#ifdef CPU_DISABLE_CMPXCHG 116100327Smarkm 11765514Sphkstatic __inline int 11865514Sphkatomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) 11965514Sphk{ 120165572Sbde u_char res; 12165514Sphk 12265514Sphk __asm __volatile( 12365514Sphk " pushfl ; " 12465514Sphk " cli ; " 125165572Sbde " cmpl %3,%4 ; " 12665514Sphk " jne 1f ; " 127150182Sjhb " movl %2,%1 ; " 12865514Sphk "1: " 129165572Sbde " sete %0 ; " 13065514Sphk " popfl ; " 13165514Sphk "# atomic_cmpset_int" 132165572Sbde : "=q" (res), /* 0 */ 133150182Sjhb "=m" (*dst) /* 1 */ 134150182Sjhb : "r" (src), /* 2 */ 135165572Sbde "r" (exp), /* 3 */ 136165572Sbde "m" (*dst) /* 4 */ 13765514Sphk : "memory"); 13865514Sphk 13965514Sphk return (res); 14065514Sphk} 141100327Smarkm 142165635Sbde#else /* !CPU_DISABLE_CMPXCHG */ 143100327Smarkm 14465514Sphkstatic __inline int 14565514Sphkatomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) 14665514Sphk{ 147165572Sbde u_char res; 14865514Sphk 149165633Sbde __asm __volatile( 150165630Sbde " " MPLOCKED " " 151150182Sjhb " cmpxchgl %2,%1 ; " 152165572Sbde " sete %0 ; " 15365514Sphk "1: " 15465514Sphk "# atomic_cmpset_int" 155165572Sbde : "=a" (res), /* 0 */ 156150182Sjhb "=m" (*dst) /* 1 */ 157150182Sjhb : "r" (src), /* 2 */ 158165572Sbde "a" (exp), /* 3 */ 159165572Sbde "m" (*dst) /* 4 */ 160150182Sjhb : "memory"); 16165514Sphk 16265514Sphk return (res); 16365514Sphk} 164100327Smarkm 165165635Sbde#endif /* CPU_DISABLE_CMPXCHG */ 166100327Smarkm 167150627Sjhb/* 168150627Sjhb * Atomically add the value of v to the integer pointed to by p and return 169150627Sjhb * the previous value of *p. 170150627Sjhb */ 171150627Sjhbstatic __inline u_int 172150627Sjhbatomic_fetchadd_int(volatile u_int *p, u_int v) 173150627Sjhb{ 174150627Sjhb 175165633Sbde __asm __volatile( 176165630Sbde " " MPLOCKED " " 177150627Sjhb " xaddl %0, %1 ; " 178150627Sjhb "# atomic_fetchadd_int" 179150627Sjhb : "+r" (v), /* 0 (result) */ 180150627Sjhb "=m" (*p) /* 1 */ 181150627Sjhb : "m" (*p)); /* 2 */ 182150627Sjhb 183150627Sjhb return (v); 184150627Sjhb} 185150627Sjhb 186137623Sjhb#if defined(_KERNEL) && !defined(SMP) 187100327Smarkm 18867351Sjhb/* 189137591Sjhb * We assume that a = b will do atomic loads and stores. However, on a 190137591Sjhb * PentiumPro or higher, reads may pass writes, so for that case we have 191137591Sjhb * to use a serializing instruction (i.e. with LOCK) to do the load in 192137591Sjhb * SMP kernels. For UP kernels, however, the cache of the single processor 193137591Sjhb * is always consistent, so we don't need any memory barriers. 19467351Sjhb */ 195147855Sjhb#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 19667351Sjhbstatic __inline u_##TYPE \ 19767351Sjhbatomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 19867351Sjhb{ \ 19967351Sjhb return (*p); \ 20067351Sjhb} \ 20167351Sjhb \ 20267351Sjhbstatic __inline void \ 20367351Sjhbatomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 20467351Sjhb{ \ 20567351Sjhb *p = v; \ 206122827Sbde} \ 207122827Sbdestruct __hack 208100327Smarkm 209165635Sbde#else /* !(_KERNEL && !SMP) */ 21067351Sjhb 211147855Sjhb#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 21271023Sjhbstatic __inline u_##TYPE \ 21371023Sjhbatomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 21471023Sjhb{ \ 21571023Sjhb u_##TYPE res; \ 21671023Sjhb \ 217165630Sbde __asm __volatile(MPLOCKED LOP \ 218165635Sbde : "=a" (res), /* 0 */ \ 219150182Sjhb "=m" (*p) /* 1 */ \ 220150182Sjhb : "m" (*p) /* 2 */ \ 221150182Sjhb : "memory"); \ 22271023Sjhb \ 22371023Sjhb return (res); \ 22471023Sjhb} \ 22571023Sjhb \ 22671023Sjhb/* \ 22771023Sjhb * The XCHG instruction asserts LOCK automagically. \ 22871023Sjhb */ \ 22971023Sjhbstatic __inline void \ 23071023Sjhbatomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 23171023Sjhb{ \ 23271023Sjhb __asm __volatile(SOP \ 233150182Sjhb : "=m" (*p), /* 0 */ \ 23471023Sjhb "+r" (v) /* 1 */ \ 235150182Sjhb : "m" (*p)); /* 2 */ \ 236122827Sbde} \ 237122827Sbdestruct __hack 238100327Smarkm 239165635Sbde#endif /* _KERNEL && !SMP */ 240100327Smarkm 241147855Sjhb#endif /* KLD_MODULE || !__GNUCLIKE_ASM */ 242100251Smarkm 243100251SmarkmATOMIC_ASM(set, char, "orb %b1,%0", "iq", v); 244100251SmarkmATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v); 245100251SmarkmATOMIC_ASM(add, char, "addb %b1,%0", "iq", v); 246100251SmarkmATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v); 24771085Sjhb 248100251SmarkmATOMIC_ASM(set, short, "orw %w1,%0", "ir", v); 249100251SmarkmATOMIC_ASM(clear, short, "andw %w1,%0", "ir", ~v); 250100251SmarkmATOMIC_ASM(add, short, "addw %w1,%0", "ir", v); 251100251SmarkmATOMIC_ASM(subtract, short, "subw %w1,%0", "ir", v); 25271085Sjhb 253100251SmarkmATOMIC_ASM(set, int, "orl %1,%0", "ir", v); 254100251SmarkmATOMIC_ASM(clear, int, "andl %1,%0", "ir", ~v); 255100251SmarkmATOMIC_ASM(add, int, "addl %1,%0", "ir", v); 256100251SmarkmATOMIC_ASM(subtract, int, "subl %1,%0", "ir", v); 25771085Sjhb 258100251SmarkmATOMIC_ASM(set, long, "orl %1,%0", "ir", v); 259100251SmarkmATOMIC_ASM(clear, long, "andl %1,%0", "ir", ~v); 260100251SmarkmATOMIC_ASM(add, long, "addl %1,%0", "ir", v); 261100251SmarkmATOMIC_ASM(subtract, long, "subl %1,%0", "ir", v); 26271085Sjhb 263100251SmarkmATOMIC_STORE_LOAD(char, "cmpxchgb %b0,%1", "xchgb %b1,%0"); 264100251SmarkmATOMIC_STORE_LOAD(short,"cmpxchgw %w0,%1", "xchgw %w1,%0"); 265100251SmarkmATOMIC_STORE_LOAD(int, "cmpxchgl %0,%1", "xchgl %1,%0"); 266100251SmarkmATOMIC_STORE_LOAD(long, "cmpxchgl %0,%1", "xchgl %1,%0"); 26771023Sjhb 26871085Sjhb#undef ATOMIC_ASM 26967351Sjhb#undef ATOMIC_STORE_LOAD 27067351Sjhb 271165635Sbde#ifndef WANT_FUNCTIONS 272147855Sjhb 273147855Sjhbstatic __inline int 274147855Sjhbatomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) 275147855Sjhb{ 276147855Sjhb 277147855Sjhb return (atomic_cmpset_int((volatile u_int *)dst, (u_int)exp, 278147855Sjhb (u_int)src)); 279147855Sjhb} 280147855Sjhb 281147855Sjhb/* Read the current value and store a zero in the destination. */ 282147855Sjhb#ifdef __GNUCLIKE_ASM 283147855Sjhb 284147855Sjhbstatic __inline u_int 285147855Sjhbatomic_readandclear_int(volatile u_int *addr) 286147855Sjhb{ 287165635Sbde u_int res; 288147855Sjhb 289165635Sbde res = 0; 290165633Sbde __asm __volatile( 291147855Sjhb " xchgl %1,%0 ; " 292147855Sjhb "# atomic_readandclear_int" 293165635Sbde : "+r" (res), /* 0 */ 294165635Sbde "=m" (*addr) /* 1 */ 295150182Sjhb : "m" (*addr)); 296147855Sjhb 297165635Sbde return (res); 298147855Sjhb} 299147855Sjhb 300147855Sjhbstatic __inline u_long 301147855Sjhbatomic_readandclear_long(volatile u_long *addr) 302147855Sjhb{ 303165635Sbde u_long res; 304147855Sjhb 305165635Sbde res = 0; 306165633Sbde __asm __volatile( 307147855Sjhb " xchgl %1,%0 ; " 308147855Sjhb "# atomic_readandclear_long" 309165635Sbde : "+r" (result), /* 0 */ 310165635Sbde "=m" (*addr) /* 1 */ 311150182Sjhb : "m" (*addr)); 312147855Sjhb 313165635Sbde return (res); 314147855Sjhb} 315147855Sjhb 316147855Sjhb#else /* !__GNUCLIKE_ASM */ 317147855Sjhb 318165635Sbdeu_int atomic_readandclear_int(volatile u_int *addr); 319165635Sbdeu_long atomic_readandclear_long(volatile u_long *addr); 320147855Sjhb 321147855Sjhb#endif /* __GNUCLIKE_ASM */ 322147855Sjhb 323147855Sjhb/* Acquire and release variants are identical to the normal ones. */ 32471085Sjhb#define atomic_set_acq_char atomic_set_char 32571085Sjhb#define atomic_set_rel_char atomic_set_char 32671085Sjhb#define atomic_clear_acq_char atomic_clear_char 32771085Sjhb#define atomic_clear_rel_char atomic_clear_char 32871085Sjhb#define atomic_add_acq_char atomic_add_char 32971085Sjhb#define atomic_add_rel_char atomic_add_char 33071085Sjhb#define atomic_subtract_acq_char atomic_subtract_char 33171085Sjhb#define atomic_subtract_rel_char atomic_subtract_char 33271085Sjhb 33371085Sjhb#define atomic_set_acq_short atomic_set_short 33471085Sjhb#define atomic_set_rel_short atomic_set_short 33571085Sjhb#define atomic_clear_acq_short atomic_clear_short 33671085Sjhb#define atomic_clear_rel_short atomic_clear_short 33771085Sjhb#define atomic_add_acq_short atomic_add_short 33871085Sjhb#define atomic_add_rel_short atomic_add_short 33971085Sjhb#define atomic_subtract_acq_short atomic_subtract_short 34071085Sjhb#define atomic_subtract_rel_short atomic_subtract_short 34171085Sjhb 34271085Sjhb#define atomic_set_acq_int atomic_set_int 34371085Sjhb#define atomic_set_rel_int atomic_set_int 34471085Sjhb#define atomic_clear_acq_int atomic_clear_int 34571085Sjhb#define atomic_clear_rel_int atomic_clear_int 34671085Sjhb#define atomic_add_acq_int atomic_add_int 34771085Sjhb#define atomic_add_rel_int atomic_add_int 34871085Sjhb#define atomic_subtract_acq_int atomic_subtract_int 34971085Sjhb#define atomic_subtract_rel_int atomic_subtract_int 350147855Sjhb#define atomic_cmpset_acq_int atomic_cmpset_int 351147855Sjhb#define atomic_cmpset_rel_int atomic_cmpset_int 35271085Sjhb 35371085Sjhb#define atomic_set_acq_long atomic_set_long 35471085Sjhb#define atomic_set_rel_long atomic_set_long 35571085Sjhb#define atomic_clear_acq_long atomic_clear_long 35671085Sjhb#define atomic_clear_rel_long atomic_clear_long 35771085Sjhb#define atomic_add_acq_long atomic_add_long 35871085Sjhb#define atomic_add_rel_long atomic_add_long 35971085Sjhb#define atomic_subtract_acq_long atomic_subtract_long 36071085Sjhb#define atomic_subtract_rel_long atomic_subtract_long 361147855Sjhb#define atomic_cmpset_acq_long atomic_cmpset_long 362147855Sjhb#define atomic_cmpset_rel_long atomic_cmpset_long 36371085Sjhb 364147855Sjhb/* Operations on 8-bit bytes. */ 36571085Sjhb#define atomic_set_8 atomic_set_char 36671085Sjhb#define atomic_set_acq_8 atomic_set_acq_char 36771085Sjhb#define atomic_set_rel_8 atomic_set_rel_char 36871085Sjhb#define atomic_clear_8 atomic_clear_char 36971085Sjhb#define atomic_clear_acq_8 atomic_clear_acq_char 37071085Sjhb#define atomic_clear_rel_8 atomic_clear_rel_char 37171085Sjhb#define atomic_add_8 atomic_add_char 37271085Sjhb#define atomic_add_acq_8 atomic_add_acq_char 37371085Sjhb#define atomic_add_rel_8 atomic_add_rel_char 37471085Sjhb#define atomic_subtract_8 atomic_subtract_char 37571085Sjhb#define atomic_subtract_acq_8 atomic_subtract_acq_char 37671085Sjhb#define atomic_subtract_rel_8 atomic_subtract_rel_char 37771085Sjhb#define atomic_load_acq_8 atomic_load_acq_char 37871085Sjhb#define atomic_store_rel_8 atomic_store_rel_char 37971085Sjhb 380147855Sjhb/* Operations on 16-bit words. */ 38171085Sjhb#define atomic_set_16 atomic_set_short 38271085Sjhb#define atomic_set_acq_16 atomic_set_acq_short 38371085Sjhb#define atomic_set_rel_16 atomic_set_rel_short 38471085Sjhb#define atomic_clear_16 atomic_clear_short 38571085Sjhb#define atomic_clear_acq_16 atomic_clear_acq_short 38671085Sjhb#define atomic_clear_rel_16 atomic_clear_rel_short 38771085Sjhb#define atomic_add_16 atomic_add_short 38871085Sjhb#define atomic_add_acq_16 atomic_add_acq_short 38971085Sjhb#define atomic_add_rel_16 atomic_add_rel_short 39071085Sjhb#define atomic_subtract_16 atomic_subtract_short 39171085Sjhb#define atomic_subtract_acq_16 atomic_subtract_acq_short 39271085Sjhb#define atomic_subtract_rel_16 atomic_subtract_rel_short 39371085Sjhb#define atomic_load_acq_16 atomic_load_acq_short 39471085Sjhb#define atomic_store_rel_16 atomic_store_rel_short 39571085Sjhb 396147855Sjhb/* Operations on 32-bit double words. */ 39771085Sjhb#define atomic_set_32 atomic_set_int 39871085Sjhb#define atomic_set_acq_32 atomic_set_acq_int 39971085Sjhb#define atomic_set_rel_32 atomic_set_rel_int 40071085Sjhb#define atomic_clear_32 atomic_clear_int 40171085Sjhb#define atomic_clear_acq_32 atomic_clear_acq_int 40271085Sjhb#define atomic_clear_rel_32 atomic_clear_rel_int 40371085Sjhb#define atomic_add_32 atomic_add_int 40471085Sjhb#define atomic_add_acq_32 atomic_add_acq_int 40571085Sjhb#define atomic_add_rel_32 atomic_add_rel_int 40671085Sjhb#define atomic_subtract_32 atomic_subtract_int 40771085Sjhb#define atomic_subtract_acq_32 atomic_subtract_acq_int 40871085Sjhb#define atomic_subtract_rel_32 atomic_subtract_rel_int 40971085Sjhb#define atomic_load_acq_32 atomic_load_acq_int 41071085Sjhb#define atomic_store_rel_32 atomic_store_rel_int 41171085Sjhb#define atomic_cmpset_32 atomic_cmpset_int 41271085Sjhb#define atomic_cmpset_acq_32 atomic_cmpset_acq_int 41371085Sjhb#define atomic_cmpset_rel_32 atomic_cmpset_rel_int 41471085Sjhb#define atomic_readandclear_32 atomic_readandclear_int 415150627Sjhb#define atomic_fetchadd_32 atomic_fetchadd_int 41671085Sjhb 417147855Sjhb/* Operations on pointers. */ 418157212Sdes#define atomic_set_ptr(p, v) \ 419157212Sdes atomic_set_int((volatile u_int *)(p), (u_int)(v)) 420157212Sdes#define atomic_set_acq_ptr(p, v) \ 421157212Sdes atomic_set_acq_int((volatile u_int *)(p), (u_int)(v)) 422157212Sdes#define atomic_set_rel_ptr(p, v) \ 423157212Sdes atomic_set_rel_int((volatile u_int *)(p), (u_int)(v)) 424157212Sdes#define atomic_clear_ptr(p, v) \ 425157212Sdes atomic_clear_int((volatile u_int *)(p), (u_int)(v)) 426157212Sdes#define atomic_clear_acq_ptr(p, v) \ 427157212Sdes atomic_clear_acq_int((volatile u_int *)(p), (u_int)(v)) 428157212Sdes#define atomic_clear_rel_ptr(p, v) \ 429157212Sdes atomic_clear_rel_int((volatile u_int *)(p), (u_int)(v)) 430157212Sdes#define atomic_add_ptr(p, v) \ 431157212Sdes atomic_add_int((volatile u_int *)(p), (u_int)(v)) 432157212Sdes#define atomic_add_acq_ptr(p, v) \ 433157212Sdes atomic_add_acq_int((volatile u_int *)(p), (u_int)(v)) 434157212Sdes#define atomic_add_rel_ptr(p, v) \ 435157212Sdes atomic_add_rel_int((volatile u_int *)(p), (u_int)(v)) 436157212Sdes#define atomic_subtract_ptr(p, v) \ 437157212Sdes atomic_subtract_int((volatile u_int *)(p), (u_int)(v)) 438157212Sdes#define atomic_subtract_acq_ptr(p, v) \ 439157212Sdes atomic_subtract_acq_int((volatile u_int *)(p), (u_int)(v)) 440157212Sdes#define atomic_subtract_rel_ptr(p, v) \ 441157212Sdes atomic_subtract_rel_int((volatile u_int *)(p), (u_int)(v)) 442157212Sdes#define atomic_load_acq_ptr(p) \ 443157212Sdes atomic_load_acq_int((volatile u_int *)(p)) 444157212Sdes#define atomic_store_rel_ptr(p, v) \ 445157212Sdes atomic_store_rel_int((volatile u_int *)(p), (v)) 446157212Sdes#define atomic_cmpset_ptr(dst, old, new) \ 447157212Sdes atomic_cmpset_int((volatile u_int *)(dst), (u_int)(old), (u_int)(new)) 448157212Sdes#define atomic_cmpset_acq_ptr(dst, old, new) \ 449165633Sbde atomic_cmpset_acq_int((volatile u_int *)(dst), (u_int)(old), \ 450165633Sbde (u_int)(new)) 451157212Sdes#define atomic_cmpset_rel_ptr(dst, old, new) \ 452165633Sbde atomic_cmpset_rel_int((volatile u_int *)(dst), (u_int)(old), \ 453165633Sbde (u_int)(new)) 454157212Sdes#define atomic_readandclear_ptr(p) \ 455157212Sdes atomic_readandclear_int((volatile u_int *)(p)) 45665514Sphk 457165635Sbde#endif /* !WANT_FUNCTIONS */ 458165633Sbde 459165633Sbde#endif /* !_MACHINE_ATOMIC_H_ */ 460