Rev 6934 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6934 | Rev 7143 | ||
---|---|---|---|
1 | #ifndef _ASM_GENERIC_ATOMIC_LONG_H |
1 | #ifndef _ASM_GENERIC_ATOMIC_LONG_H |
2 | #define _ASM_GENERIC_ATOMIC_LONG_H |
2 | #define _ASM_GENERIC_ATOMIC_LONG_H |
3 | /* |
3 | /* |
4 | * Copyright (C) 2005 Silicon Graphics, Inc. |
4 | * Copyright (C) 2005 Silicon Graphics, Inc. |
5 | * Christoph Lameter |
5 | * Christoph Lameter |
6 | * |
6 | * |
7 | * Allows to provide arch independent atomic definitions without the need to |
7 | * Allows to provide arch independent atomic definitions without the need to |
8 | * edit all arch specific atomic.h files. |
8 | * edit all arch specific atomic.h files. |
9 | */ |
9 | */ |
10 | 10 | ||
11 | #include |
11 | #include |
12 | 12 | ||
13 | /* |
13 | /* |
14 | * Suppport for atomic_long_t |
14 | * Suppport for atomic_long_t |
15 | * |
15 | * |
16 | * Casts for parameters are avoided for existing atomic functions in order to |
16 | * Casts for parameters are avoided for existing atomic functions in order to |
17 | * avoid issues with cast-as-lval under gcc 4.x and other limitations that the |
17 | * avoid issues with cast-as-lval under gcc 4.x and other limitations that the |
18 | * macros of a platform may have. |
18 | * macros of a platform may have. |
19 | */ |
19 | */ |
20 | 20 | ||
21 | #if BITS_PER_LONG == 64 |
21 | #if BITS_PER_LONG == 64 |
22 | 22 | ||
23 | typedef atomic64_t atomic_long_t; |
23 | typedef atomic64_t atomic_long_t; |
24 | 24 | ||
25 | #define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i) |
25 | #define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i) |
26 | #define ATOMIC_LONG_PFX(x) atomic64 ## x |
26 | #define ATOMIC_LONG_PFX(x) atomic64 ## x |
27 | 27 | ||
28 | #else |
28 | #else |
29 | 29 | ||
30 | typedef atomic_t atomic_long_t; |
30 | typedef atomic_t atomic_long_t; |
31 | 31 | ||
32 | #define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i) |
32 | #define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i) |
33 | #define ATOMIC_LONG_PFX(x) atomic ## x |
33 | #define ATOMIC_LONG_PFX(x) atomic ## x |
34 | 34 | ||
35 | #endif |
35 | #endif |
36 | 36 | ||
37 | #define ATOMIC_LONG_READ_OP(mo) \ |
37 | #define ATOMIC_LONG_READ_OP(mo) \ |
38 | static inline long atomic_long_read##mo(const atomic_long_t *l) \ |
38 | static inline long atomic_long_read##mo(const atomic_long_t *l) \ |
39 | { \ |
39 | { \ |
40 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
40 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
41 | \ |
41 | \ |
42 | return (long)ATOMIC_LONG_PFX(_read##mo)(v); \ |
42 | return (long)ATOMIC_LONG_PFX(_read##mo)(v); \ |
43 | } |
43 | } |
44 | ATOMIC_LONG_READ_OP() |
44 | ATOMIC_LONG_READ_OP() |
45 | ATOMIC_LONG_READ_OP(_acquire) |
45 | ATOMIC_LONG_READ_OP(_acquire) |
46 | 46 | ||
47 | #undef ATOMIC_LONG_READ_OP |
47 | #undef ATOMIC_LONG_READ_OP |
48 | 48 | ||
49 | #define ATOMIC_LONG_SET_OP(mo) \ |
49 | #define ATOMIC_LONG_SET_OP(mo) \ |
50 | static inline void atomic_long_set##mo(atomic_long_t *l, long i) \ |
50 | static inline void atomic_long_set##mo(atomic_long_t *l, long i) \ |
51 | { \ |
51 | { \ |
52 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
52 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
53 | \ |
53 | \ |
54 | ATOMIC_LONG_PFX(_set##mo)(v, i); \ |
54 | ATOMIC_LONG_PFX(_set##mo)(v, i); \ |
55 | } |
55 | } |
56 | ATOMIC_LONG_SET_OP() |
56 | ATOMIC_LONG_SET_OP() |
57 | ATOMIC_LONG_SET_OP(_release) |
57 | ATOMIC_LONG_SET_OP(_release) |
58 | 58 | ||
59 | #undef ATOMIC_LONG_SET_OP |
59 | #undef ATOMIC_LONG_SET_OP |
60 | 60 | ||
61 | #define ATOMIC_LONG_ADD_SUB_OP(op, mo) \ |
61 | #define ATOMIC_LONG_ADD_SUB_OP(op, mo) \ |
62 | static inline long \ |
62 | static inline long \ |
63 | atomic_long_##op##_return##mo(long i, atomic_long_t *l) \ |
63 | atomic_long_##op##_return##mo(long i, atomic_long_t *l) \ |
64 | { \ |
64 | { \ |
65 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
65 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
66 | \ |
66 | \ |
67 | return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(i, v); \ |
67 | return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(i, v); \ |
68 | } |
68 | } |
69 | ATOMIC_LONG_ADD_SUB_OP(add,) |
69 | ATOMIC_LONG_ADD_SUB_OP(add,) |
70 | ATOMIC_LONG_ADD_SUB_OP(add, _relaxed) |
70 | ATOMIC_LONG_ADD_SUB_OP(add, _relaxed) |
71 | ATOMIC_LONG_ADD_SUB_OP(add, _acquire) |
71 | ATOMIC_LONG_ADD_SUB_OP(add, _acquire) |
72 | ATOMIC_LONG_ADD_SUB_OP(add, _release) |
72 | ATOMIC_LONG_ADD_SUB_OP(add, _release) |
73 | ATOMIC_LONG_ADD_SUB_OP(sub,) |
73 | ATOMIC_LONG_ADD_SUB_OP(sub,) |
74 | ATOMIC_LONG_ADD_SUB_OP(sub, _relaxed) |
74 | ATOMIC_LONG_ADD_SUB_OP(sub, _relaxed) |
75 | ATOMIC_LONG_ADD_SUB_OP(sub, _acquire) |
75 | ATOMIC_LONG_ADD_SUB_OP(sub, _acquire) |
76 | ATOMIC_LONG_ADD_SUB_OP(sub, _release) |
76 | ATOMIC_LONG_ADD_SUB_OP(sub, _release) |
77 | 77 | ||
78 | #undef ATOMIC_LONG_ADD_SUB_OP |
78 | #undef ATOMIC_LONG_ADD_SUB_OP |
79 | 79 | ||
80 | #define atomic_long_cmpxchg_relaxed(l, old, new) \ |
80 | #define atomic_long_cmpxchg_relaxed(l, old, new) \ |
81 | (ATOMIC_LONG_PFX(_cmpxchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(l), \ |
81 | (ATOMIC_LONG_PFX(_cmpxchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(l), \ |
82 | (old), (new))) |
82 | (old), (new))) |
83 | #define atomic_long_cmpxchg_acquire(l, old, new) \ |
83 | #define atomic_long_cmpxchg_acquire(l, old, new) \ |
84 | (ATOMIC_LONG_PFX(_cmpxchg_acquire)((ATOMIC_LONG_PFX(_t) *)(l), \ |
84 | (ATOMIC_LONG_PFX(_cmpxchg_acquire)((ATOMIC_LONG_PFX(_t) *)(l), \ |
85 | (old), (new))) |
85 | (old), (new))) |
86 | #define atomic_long_cmpxchg_release(l, old, new) \ |
86 | #define atomic_long_cmpxchg_release(l, old, new) \ |
87 | (ATOMIC_LONG_PFX(_cmpxchg_release)((ATOMIC_LONG_PFX(_t) *)(l), \ |
87 | (ATOMIC_LONG_PFX(_cmpxchg_release)((ATOMIC_LONG_PFX(_t) *)(l), \ |
88 | (old), (new))) |
88 | (old), (new))) |
89 | #define atomic_long_cmpxchg(l, old, new) \ |
89 | #define atomic_long_cmpxchg(l, old, new) \ |
90 | (ATOMIC_LONG_PFX(_cmpxchg)((ATOMIC_LONG_PFX(_t) *)(l), (old), (new))) |
90 | (ATOMIC_LONG_PFX(_cmpxchg)((ATOMIC_LONG_PFX(_t) *)(l), (old), (new))) |
91 | 91 | ||
92 | #define atomic_long_xchg_relaxed(v, new) \ |
92 | #define atomic_long_xchg_relaxed(v, new) \ |
93 | (ATOMIC_LONG_PFX(_xchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
93 | (ATOMIC_LONG_PFX(_xchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
94 | #define atomic_long_xchg_acquire(v, new) \ |
94 | #define atomic_long_xchg_acquire(v, new) \ |
95 | (ATOMIC_LONG_PFX(_xchg_acquire)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
95 | (ATOMIC_LONG_PFX(_xchg_acquire)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
96 | #define atomic_long_xchg_release(v, new) \ |
96 | #define atomic_long_xchg_release(v, new) \ |
97 | (ATOMIC_LONG_PFX(_xchg_release)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
97 | (ATOMIC_LONG_PFX(_xchg_release)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
98 | #define atomic_long_xchg(v, new) \ |
98 | #define atomic_long_xchg(v, new) \ |
99 | (ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
99 | (ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
100 | 100 | ||
101 | static inline void atomic_long_inc(atomic_long_t *l) |
101 | static __always_inline void atomic_long_inc(atomic_long_t *l) |
102 | { |
102 | { |
103 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
103 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
104 | 104 | ||
105 | ATOMIC_LONG_PFX(_inc)(v); |
105 | ATOMIC_LONG_PFX(_inc)(v); |
106 | } |
106 | } |
107 | 107 | ||
108 | static inline void atomic_long_dec(atomic_long_t *l) |
108 | static __always_inline void atomic_long_dec(atomic_long_t *l) |
109 | { |
109 | { |
110 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
110 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
111 | 111 | ||
112 | ATOMIC_LONG_PFX(_dec)(v); |
112 | ATOMIC_LONG_PFX(_dec)(v); |
113 | } |
113 | } |
114 | 114 | ||
115 | #define ATOMIC_LONG_OP(op) \ |
115 | #define ATOMIC_LONG_OP(op) \ |
116 | static inline void \ |
116 | static __always_inline void \ |
117 | atomic_long_##op(long i, atomic_long_t *l) \ |
117 | atomic_long_##op(long i, atomic_long_t *l) \ |
118 | { \ |
118 | { \ |
119 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
119 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
120 | \ |
120 | \ |
121 | ATOMIC_LONG_PFX(_##op)(i, v); \ |
121 | ATOMIC_LONG_PFX(_##op)(i, v); \ |
122 | } |
122 | } |
123 | 123 | ||
124 | ATOMIC_LONG_OP(add) |
124 | ATOMIC_LONG_OP(add) |
125 | ATOMIC_LONG_OP(sub) |
125 | ATOMIC_LONG_OP(sub) |
126 | ATOMIC_LONG_OP(and) |
126 | ATOMIC_LONG_OP(and) |
127 | ATOMIC_LONG_OP(or) |
127 | ATOMIC_LONG_OP(or) |
128 | ATOMIC_LONG_OP(xor) |
128 | ATOMIC_LONG_OP(xor) |
129 | ATOMIC_LONG_OP(andnot) |
129 | ATOMIC_LONG_OP(andnot) |
130 | 130 | ||
131 | #undef ATOMIC_LONG_OP |
131 | #undef ATOMIC_LONG_OP |
132 | 132 | ||
133 | static inline int atomic_long_sub_and_test(long i, atomic_long_t *l) |
133 | static inline int atomic_long_sub_and_test(long i, atomic_long_t *l) |
134 | { |
134 | { |
135 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
135 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
136 | 136 | ||
137 | return ATOMIC_LONG_PFX(_sub_and_test)(i, v); |
137 | return ATOMIC_LONG_PFX(_sub_and_test)(i, v); |
138 | } |
138 | } |
139 | 139 | ||
140 | static inline int atomic_long_dec_and_test(atomic_long_t *l) |
140 | static inline int atomic_long_dec_and_test(atomic_long_t *l) |
141 | { |
141 | { |
142 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
142 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
143 | 143 | ||
144 | return ATOMIC_LONG_PFX(_dec_and_test)(v); |
144 | return ATOMIC_LONG_PFX(_dec_and_test)(v); |
145 | } |
145 | } |
146 | 146 | ||
147 | static inline int atomic_long_inc_and_test(atomic_long_t *l) |
147 | static inline int atomic_long_inc_and_test(atomic_long_t *l) |
148 | { |
148 | { |
149 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
149 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
150 | 150 | ||
151 | return ATOMIC_LONG_PFX(_inc_and_test)(v); |
151 | return ATOMIC_LONG_PFX(_inc_and_test)(v); |
152 | } |
152 | } |
153 | 153 | ||
154 | static inline int atomic_long_add_negative(long i, atomic_long_t *l) |
154 | static inline int atomic_long_add_negative(long i, atomic_long_t *l) |
155 | { |
155 | { |
156 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
156 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
157 | 157 | ||
158 | return ATOMIC_LONG_PFX(_add_negative)(i, v); |
158 | return ATOMIC_LONG_PFX(_add_negative)(i, v); |
159 | } |
159 | } |
160 | 160 | ||
161 | #define ATOMIC_LONG_INC_DEC_OP(op, mo) \ |
161 | #define ATOMIC_LONG_INC_DEC_OP(op, mo) \ |
162 | static inline long \ |
162 | static inline long \ |
163 | atomic_long_##op##_return##mo(atomic_long_t *l) \ |
163 | atomic_long_##op##_return##mo(atomic_long_t *l) \ |
164 | { \ |
164 | { \ |
165 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
165 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |
166 | \ |
166 | \ |
167 | return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(v); \ |
167 | return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(v); \ |
168 | } |
168 | } |
169 | ATOMIC_LONG_INC_DEC_OP(inc,) |
169 | ATOMIC_LONG_INC_DEC_OP(inc,) |
170 | ATOMIC_LONG_INC_DEC_OP(inc, _relaxed) |
170 | ATOMIC_LONG_INC_DEC_OP(inc, _relaxed) |
171 | ATOMIC_LONG_INC_DEC_OP(inc, _acquire) |
171 | ATOMIC_LONG_INC_DEC_OP(inc, _acquire) |
172 | ATOMIC_LONG_INC_DEC_OP(inc, _release) |
172 | ATOMIC_LONG_INC_DEC_OP(inc, _release) |
173 | ATOMIC_LONG_INC_DEC_OP(dec,) |
173 | ATOMIC_LONG_INC_DEC_OP(dec,) |
174 | ATOMIC_LONG_INC_DEC_OP(dec, _relaxed) |
174 | ATOMIC_LONG_INC_DEC_OP(dec, _relaxed) |
175 | ATOMIC_LONG_INC_DEC_OP(dec, _acquire) |
175 | ATOMIC_LONG_INC_DEC_OP(dec, _acquire) |
176 | ATOMIC_LONG_INC_DEC_OP(dec, _release) |
176 | ATOMIC_LONG_INC_DEC_OP(dec, _release) |
177 | 177 | ||
178 | #undef ATOMIC_LONG_INC_DEC_OP |
178 | #undef ATOMIC_LONG_INC_DEC_OP |
179 | 179 | ||
180 | static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) |
180 | static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) |
181 | { |
181 | { |
182 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
182 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
183 | 183 | ||
184 | return (long)ATOMIC_LONG_PFX(_add_unless)(v, a, u); |
184 | return (long)ATOMIC_LONG_PFX(_add_unless)(v, a, u); |
185 | } |
185 | } |
186 | 186 | ||
187 | #define atomic_long_inc_not_zero(l) \ |
187 | #define atomic_long_inc_not_zero(l) \ |
188 | ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l)) |
188 | ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l)) |
189 | 189 | ||
190 | #endif /* _ASM_GENERIC_ATOMIC_LONG_H */ |
190 | #endif /* _ASM_GENERIC_ATOMIC_LONG_H */ |