Deleted Added
full compact
atomic.h (137784) 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/i386/include/atomic.h 137784 2004-11-16 20:42:32Z jhb $
26 * $FreeBSD: head/sys/i386/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))

--- 31 unchanged lines hidden (view full) ---

70int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
71
72#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
73u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
74void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
75
76#else /* !KLD_MODULE */
77
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))

--- 31 unchanged lines hidden (view full) ---

74int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
75
76#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
77u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
78void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
79
80#else /* !KLD_MODULE */
81
78#if defined(__GNUC__) || defined(__INTEL_COMPILER)
82#ifdef __GNUCLIKE_ASM
79
80/*
81 * For userland, assume the SMP case and use lock prefixes so that
82 * the binaries will run on both types of systems.
83 */
84#if defined(SMP) || !defined(_KERNEL)
85#define MPLOCKED lock ;
86#else

--- 9 unchanged lines hidden (view full) ---

96atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
97{ \
98 __asm __volatile(__XSTRING(MPLOCKED) OP \
99 : "+m" (*p) \
100 : CONS (V)); \
101} \
102struct __hack
103
83
84/*
85 * For userland, assume the SMP case and use lock prefixes so that
86 * the binaries will run on both types of systems.
87 */
88#if defined(SMP) || !defined(_KERNEL)
89#define MPLOCKED lock ;
90#else

--- 9 unchanged lines hidden (view full) ---

100atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
101{ \
102 __asm __volatile(__XSTRING(MPLOCKED) OP \
103 : "+m" (*p) \
104 : CONS (V)); \
105} \
106struct __hack
107
104#else /* !(__GNUC__ || __INTEL_COMPILER) */
108#else /* !__GNUCLIKE_ASM */
105
106#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
107extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
108
109
110#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
111extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
112
109#endif /* __GNUC__ || __INTEL_COMPILER */
113#endif /* __GNUCLIKE_ASM */
110
111/*
112 * Atomic compare and set, used by the mutex functions
113 *
114 * if (*dst == exp) *dst = src (all 32 bit words)
115 *
116 * Returns 0 on failure, non-zero on success
117 */
118
114
115/*
116 * Atomic compare and set, used by the mutex functions
117 *
118 * if (*dst == exp) *dst = src (all 32 bit words)
119 *
120 * Returns 0 on failure, non-zero on success
121 */
122
119#if defined(__GNUC__) || defined(__INTEL_COMPILER)
123#ifdef __GNUCLIKE_ASM
120
121#if defined(CPU_DISABLE_CMPXCHG)
122
123static __inline int
124atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
125{
126 int res = exp;
127

--- 35 unchanged lines hidden (view full) ---

163 "m" (*(dst)) /* 2 */
164 : "memory");
165
166 return (res);
167}
168
169#endif /* defined(CPU_DISABLE_CMPXCHG) */
170
124
125#if defined(CPU_DISABLE_CMPXCHG)
126
127static __inline int
128atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
129{
130 int res = exp;
131

--- 35 unchanged lines hidden (view full) ---

167 "m" (*(dst)) /* 2 */
168 : "memory");
169
170 return (res);
171}
172
173#endif /* defined(CPU_DISABLE_CMPXCHG) */
174
171#endif /* defined(__GNUC__) || defined(__INTEL_COMPILER) */
175#endif /* __GNUCLIKE_ASM */
172
176
173#if defined(__GNUC__) || defined(__INTEL_COMPILER)
177#ifdef __GNUCLIKE_ASM
174
175#if defined(_KERNEL) && !defined(SMP)
176
177/*
178 * We assume that a = b will do atomic loads and stores. However, on a
179 * PentiumPro or higher, reads may pass writes, so for that case we have
180 * to use a serializing instruction (i.e. with LOCK) to do the load in
181 * SMP kernels. For UP kernels, however, the cache of the single processor

--- 39 unchanged lines hidden (view full) ---

221 : "+m" (*p), /* 0 */ \
222 "+r" (v) /* 1 */ \
223 : : "memory"); \
224} \
225struct __hack
226
227#endif /* !defined(SMP) */
228
178
179#if defined(_KERNEL) && !defined(SMP)
180
181/*
182 * We assume that a = b will do atomic loads and stores. However, on a
183 * PentiumPro or higher, reads may pass writes, so for that case we have
184 * to use a serializing instruction (i.e. with LOCK) to do the load in
185 * SMP kernels. For UP kernels, however, the cache of the single processor

--- 39 unchanged lines hidden (view full) ---

225 : "+m" (*p), /* 0 */ \
226 "+r" (v) /* 1 */ \
227 : : "memory"); \
228} \
229struct __hack
230
231#endif /* !defined(SMP) */
232
229#else /* !(defined(__GNUC__) || defined(__INTEL_COMPILER)) */
233#else /* !__GNUCLIKE_ASM */
230
231extern int atomic_cmpset_int(volatile u_int *, u_int, u_int);
232
233#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
234extern u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
235extern void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
236
234
235extern int atomic_cmpset_int(volatile u_int *, u_int, u_int);
236
237#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
238extern u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
239extern void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
240
237#endif /* defined(__GNUC__) || defined(__INTEL_COMPILER) */
241#endif /* __GNUCLIKE_ASM */
238
239#endif /* KLD_MODULE */
240
241ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v);
242ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v);
243ATOMIC_ASM(add, char, "addb %b1,%0", "iq", v);
244ATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v);
245

--- 159 unchanged lines hidden (view full) ---

405
406ATOMIC_PTR(set)
407ATOMIC_PTR(clear)
408ATOMIC_PTR(add)
409ATOMIC_PTR(subtract)
410
411#undef ATOMIC_PTR
412
242
243#endif /* KLD_MODULE */
244
245ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v);
246ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v);
247ATOMIC_ASM(add, char, "addb %b1,%0", "iq", v);
248ATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v);
249

--- 159 unchanged lines hidden (view full) ---

409
410ATOMIC_PTR(set)
411ATOMIC_PTR(clear)
412ATOMIC_PTR(add)
413ATOMIC_PTR(subtract)
414
415#undef ATOMIC_PTR
416
413#if defined(__GNUC__) || defined(__INTEL_COMPILER)
417#ifdef __GNUCLIKE_ASM
414
415static __inline u_int
416atomic_readandclear_int(volatile u_int *addr)
417{
418 u_int result;
419
420 __asm __volatile (
421 " xorl %0,%0 ; "

--- 15 unchanged lines hidden (view full) ---

437 " xchgl %1,%0 ; "
438 "# atomic_readandclear_int"
439 : "=&r" (result) /* 0 (result) */
440 : "m" (*addr)); /* 1 (addr) */
441
442 return (result);
443}
444
418
419static __inline u_int
420atomic_readandclear_int(volatile u_int *addr)
421{
422 u_int result;
423
424 __asm __volatile (
425 " xorl %0,%0 ; "

--- 15 unchanged lines hidden (view full) ---

441 " xchgl %1,%0 ; "
442 "# atomic_readandclear_int"
443 : "=&r" (result) /* 0 (result) */
444 : "m" (*addr)); /* 1 (addr) */
445
446 return (result);
447}
448
445#else /* !(defined(__GNUC__) || defined(__INTEL_COMPILER)) */
449#else /* !__GNUCLIKE_ASM */
446
447extern u_long atomic_readandclear_long(volatile u_long *);
448extern u_int atomic_readandclear_int(volatile u_int *);
449
450
451extern u_long atomic_readandclear_long(volatile u_long *);
452extern u_int atomic_readandclear_int(volatile u_int *);
453
450#endif /* defined(__GNUC__) || defined(__INTEL_COMPILER) */
454#endif /* __GNUCLIKE_ASM */
451
452#endif /* !defined(WANT_FUNCTIONS) */
453#endif /* ! _MACHINE_ATOMIC_H_ */
455
456#endif /* !defined(WANT_FUNCTIONS) */
457#endif /* ! _MACHINE_ATOMIC_H_ */