atomic.h (122940) | atomic.h (143063) |
---|---|
1/*- 2 * Copyright (c) 1998 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 1998 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/amd64/include/atomic.h 122940 2003-11-21 03:02:00Z peter $ | 26 * $FreeBSD: head/sys/amd64/include/atomic.h 143063 2005-03-02 21:33:29Z joerg $ |
27 */ 28#ifndef _MACHINE_ATOMIC_H_ 29#define _MACHINE_ATOMIC_H_ 30 | 27 */ 28#ifndef _MACHINE_ATOMIC_H_ 29#define _MACHINE_ATOMIC_H_ 30 |
31#ifndef _SYS_CDEFS_H_ 32#error this file needs sys/cdefs.h as a prerequisite 33#endif 34 |
|
31/* 32 * Various simple arithmetic on memory which is atomic in the presence 33 * of interrupts and multiple processors. 34 * 35 * atomic_set_char(P, V) (*(u_char*)(P) |= (V)) 36 * atomic_clear_char(P, V) (*(u_char*)(P) &= ~(V)) 37 * atomic_add_char(P, V) (*(u_char*)(P) += (V)) 38 * atomic_subtract_char(P, V) (*(u_char*)(P) -= (V)) --- 32 unchanged lines hidden (view full) --- 71int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src); 72 73#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 74u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 75void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 76 77#else /* !KLD_MODULE */ 78 | 35/* 36 * Various simple arithmetic on memory which is atomic in the presence 37 * of interrupts and multiple processors. 38 * 39 * atomic_set_char(P, V) (*(u_char*)(P) |= (V)) 40 * atomic_clear_char(P, V) (*(u_char*)(P) &= ~(V)) 41 * atomic_add_char(P, V) (*(u_char*)(P) += (V)) 42 * atomic_subtract_char(P, V) (*(u_char*)(P) -= (V)) --- 32 unchanged lines hidden (view full) --- 75int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src); 76 77#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 78u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 79void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 80 81#else /* !KLD_MODULE */ 82 |
79#ifdef __GNUC__ | 83#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) |
80 81/* 82 * For userland, assume the SMP case and use lock prefixes so that 83 * the binaries will run on both types of systems. 84 */ 85#if defined(SMP) || !defined(_KERNEL) 86#define MPLOCKED lock ; 87#else --- 9 unchanged lines hidden (view full) --- 97atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 98{ \ 99 __asm __volatile(__XSTRING(MPLOCKED) OP \ 100 : "+m" (*p) \ 101 : CONS (V)); \ 102} \ 103struct __hack 104 | 84 85/* 86 * For userland, assume the SMP case and use lock prefixes so that 87 * the binaries will run on both types of systems. 88 */ 89#if defined(SMP) || !defined(_KERNEL) 90#define MPLOCKED lock ; 91#else --- 9 unchanged lines hidden (view full) --- 101atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ 102{ \ 103 __asm __volatile(__XSTRING(MPLOCKED) OP \ 104 : "+m" (*p) \ 105 : CONS (V)); \ 106} \ 107struct __hack 108 |
105#else /* !__GNUC__ */ | 109#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ |
106 107#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 108extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 109 | 110 111#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ 112extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 113 |
110#endif /* __GNUC__ */ | 114#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ |
111 112/* 113 * Atomic compare and set, used by the mutex functions 114 * 115 * if (*dst == exp) *dst = src (all 32 bit words) 116 * 117 * Returns 0 on failure, non-zero on success 118 */ 119 | 115 116/* 117 * Atomic compare and set, used by the mutex functions 118 * 119 * if (*dst == exp) *dst = src (all 32 bit words) 120 * 121 * Returns 0 on failure, non-zero on success 122 */ 123 |
120#if defined(__GNUC__) | 124#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) |
121 122static __inline int 123atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) 124{ 125 int res = exp; 126 127 __asm __volatile ( 128 " " __XSTRING(MPLOCKED) " " --- 24 unchanged lines hidden (view full) --- 153 "# atomic_cmpset_long" 154 : "+a" (res) /* 0 (result) */ 155 : "r" (src), /* 1 */ 156 "m" (*(dst)) /* 2 */ 157 : "memory"); 158 159 return (res); 160} | 125 126static __inline int 127atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) 128{ 129 int res = exp; 130 131 __asm __volatile ( 132 " " __XSTRING(MPLOCKED) " " --- 24 unchanged lines hidden (view full) --- 157 "# atomic_cmpset_long" 158 : "+a" (res) /* 0 (result) */ 159 : "r" (src), /* 1 */ 160 "m" (*(dst)) /* 2 */ 161 : "memory"); 162 163 return (res); 164} |
161#endif /* defined(__GNUC__) */ | 165#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ |
162 | 166 |
163#if defined(__GNUC__) | 167#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) |
164 165#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 166static __inline u_##TYPE \ 167atomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 168{ \ 169 u_##TYPE res; \ 170 \ 171 __asm __volatile(__XSTRING(MPLOCKED) LOP \ --- 12 unchanged lines hidden (view full) --- 184{ \ 185 __asm __volatile(SOP \ 186 : "+m" (*p), /* 0 */ \ 187 "+r" (v) /* 1 */ \ 188 : : "memory"); \ 189} \ 190struct __hack 191 | 168 169#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 170static __inline u_##TYPE \ 171atomic_load_acq_##TYPE(volatile u_##TYPE *p) \ 172{ \ 173 u_##TYPE res; \ 174 \ 175 __asm __volatile(__XSTRING(MPLOCKED) LOP \ --- 12 unchanged lines hidden (view full) --- 188{ \ 189 __asm __volatile(SOP \ 190 : "+m" (*p), /* 0 */ \ 191 "+r" (v) /* 1 */ \ 192 : : "memory"); \ 193} \ 194struct __hack 195 |
192#else /* !defined(__GNUC__) */ | 196#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ |
193 194extern int atomic_cmpset_int(volatile u_int *, u_int, u_int); 195extern int atomic_cmpset_long(volatile u_long *, u_long, u_long); 196 197#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 198extern u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 199extern void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 200 | 197 198extern int atomic_cmpset_int(volatile u_int *, u_int, u_int); 199extern int atomic_cmpset_long(volatile u_long *, u_long, u_long); 200 201#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \ 202extern u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \ 203extern void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) 204 |
201#endif /* defined(__GNUC__) */ | 205#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ |
202 203#endif /* KLD_MODULE */ 204 205ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v); 206ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v); 207ATOMIC_ASM(add, char, "addb %b1,%0", "iq", v); 208ATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v); 209 --- 156 unchanged lines hidden (view full) --- 366 367ATOMIC_PTR(set) 368ATOMIC_PTR(clear) 369ATOMIC_PTR(add) 370ATOMIC_PTR(subtract) 371 372#undef ATOMIC_PTR 373 | 206 207#endif /* KLD_MODULE */ 208 209ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v); 210ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v); 211ATOMIC_ASM(add, char, "addb %b1,%0", "iq", v); 212ATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v); 213 --- 156 unchanged lines hidden (view full) --- 370 371ATOMIC_PTR(set) 372ATOMIC_PTR(clear) 373ATOMIC_PTR(add) 374ATOMIC_PTR(subtract) 375 376#undef ATOMIC_PTR 377 |
374#if defined(__GNUC__) | 378#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) |
375 376static __inline u_int 377atomic_readandclear_int(volatile u_int *addr) 378{ 379 u_int result; 380 381 __asm __volatile ( 382 " xorl %0,%0 ; " --- 15 unchanged lines hidden (view full) --- 398 " xchgq %1,%0 ; " 399 "# atomic_readandclear_int" 400 : "=&r" (result) /* 0 (result) */ 401 : "m" (*addr)); /* 1 (addr) */ 402 403 return (result); 404} 405 | 379 380static __inline u_int 381atomic_readandclear_int(volatile u_int *addr) 382{ 383 u_int result; 384 385 __asm __volatile ( 386 " xorl %0,%0 ; " --- 15 unchanged lines hidden (view full) --- 402 " xchgq %1,%0 ; " 403 "# atomic_readandclear_int" 404 : "=&r" (result) /* 0 (result) */ 405 : "m" (*addr)); /* 1 (addr) */ 406 407 return (result); 408} 409 |
406#else /* !defined(__GNUC__) */ | 410#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ |
407 408extern u_long atomic_readandclear_long(volatile u_long *); 409extern u_int atomic_readandclear_int(volatile u_int *); 410 | 411 412extern u_long atomic_readandclear_long(volatile u_long *); 413extern u_int atomic_readandclear_int(volatile u_int *); 414 |
411#endif /* defined(__GNUC__) */ | 415#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ |
412 413#endif /* !defined(WANT_FUNCTIONS) */ 414#endif /* ! _MACHINE_ATOMIC_H_ */ | 416 417#endif /* !defined(WANT_FUNCTIONS) */ 418#endif /* ! _MACHINE_ATOMIC_H_ */ |