Deleted Added
full compact
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_ */