Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/tile/include/asm/atomic.h
10819 views
1
/*
2
* Copyright 2010 Tilera Corporation. All Rights Reserved.
3
*
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation, version 2.
7
*
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11
* NON INFRINGEMENT. See the GNU General Public License for
12
* more details.
13
*
14
* Atomic primitives.
15
*/
16
17
#ifndef _ASM_TILE_ATOMIC_H
18
#define _ASM_TILE_ATOMIC_H
19
20
#ifndef __ASSEMBLY__
21
22
#include <linux/compiler.h>
23
#include <asm/system.h>
24
25
#define ATOMIC_INIT(i) { (i) }
26
27
/**
28
* atomic_read - read atomic variable
29
* @v: pointer of type atomic_t
30
*
31
* Atomically reads the value of @v.
32
*/
33
static inline int atomic_read(const atomic_t *v)
34
{
35
return ACCESS_ONCE(v->counter);
36
}
37
38
/**
39
* atomic_sub_return - subtract integer and return
40
* @v: pointer of type atomic_t
41
* @i: integer value to subtract
42
*
43
* Atomically subtracts @i from @v and returns @v - @i
44
*/
45
#define atomic_sub_return(i, v) atomic_add_return((int)(-(i)), (v))
46
47
/**
48
* atomic_sub - subtract integer from atomic variable
49
* @i: integer value to subtract
50
* @v: pointer of type atomic_t
51
*
52
* Atomically subtracts @i from @v.
53
*/
54
#define atomic_sub(i, v) atomic_add((int)(-(i)), (v))
55
56
/**
57
* atomic_sub_and_test - subtract value from variable and test result
58
* @i: integer value to subtract
59
* @v: pointer of type atomic_t
60
*
61
* Atomically subtracts @i from @v and returns true if the result is
62
* zero, or false for all other cases.
63
*/
64
#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
65
66
/**
67
* atomic_inc_return - increment memory and return
68
* @v: pointer of type atomic_t
69
*
70
* Atomically increments @v by 1 and returns the new value.
71
*/
72
#define atomic_inc_return(v) atomic_add_return(1, (v))
73
74
/**
75
* atomic_dec_return - decrement memory and return
76
* @v: pointer of type atomic_t
77
*
78
* Atomically decrements @v by 1 and returns the new value.
79
*/
80
#define atomic_dec_return(v) atomic_sub_return(1, (v))
81
82
/**
83
* atomic_inc - increment atomic variable
84
* @v: pointer of type atomic_t
85
*
86
* Atomically increments @v by 1.
87
*/
88
#define atomic_inc(v) atomic_add(1, (v))
89
90
/**
91
* atomic_dec - decrement atomic variable
92
* @v: pointer of type atomic_t
93
*
94
* Atomically decrements @v by 1.
95
*/
96
#define atomic_dec(v) atomic_sub(1, (v))
97
98
/**
99
* atomic_dec_and_test - decrement and test
100
* @v: pointer of type atomic_t
101
*
102
* Atomically decrements @v by 1 and returns true if the result is 0.
103
*/
104
#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
105
106
/**
107
* atomic_inc_and_test - increment and test
108
* @v: pointer of type atomic_t
109
*
110
* Atomically increments @v by 1 and returns true if the result is 0.
111
*/
112
#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
113
114
/**
115
* atomic_add_negative - add and test if negative
116
* @v: pointer of type atomic_t
117
* @i: integer value to add
118
*
119
* Atomically adds @i to @v and returns true if the result is
120
* negative, or false when result is greater than or equal to zero.
121
*/
122
#define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0)
123
124
/**
125
* atomic_inc_not_zero - increment unless the number is zero
126
* @v: pointer of type atomic_t
127
*
128
* Atomically increments @v by 1, so long as @v is non-zero.
129
* Returns non-zero if @v was non-zero, and zero otherwise.
130
*/
131
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
132
133
/* Nonexistent functions intended to cause link errors. */
134
extern unsigned long __xchg_called_with_bad_pointer(void);
135
extern unsigned long __cmpxchg_called_with_bad_pointer(void);
136
137
#define xchg(ptr, x) \
138
({ \
139
typeof(*(ptr)) __x; \
140
switch (sizeof(*(ptr))) { \
141
case 4: \
142
__x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \
143
(atomic_t *)(ptr), \
144
(u32)(typeof((x)-(x)))(x)); \
145
break; \
146
case 8: \
147
__x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \
148
(atomic64_t *)(ptr), \
149
(u64)(typeof((x)-(x)))(x)); \
150
break; \
151
default: \
152
__xchg_called_with_bad_pointer(); \
153
} \
154
__x; \
155
})
156
157
#define cmpxchg(ptr, o, n) \
158
({ \
159
typeof(*(ptr)) __x; \
160
switch (sizeof(*(ptr))) { \
161
case 4: \
162
__x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \
163
(atomic_t *)(ptr), \
164
(u32)(typeof((o)-(o)))(o), \
165
(u32)(typeof((n)-(n)))(n)); \
166
break; \
167
case 8: \
168
__x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \
169
(atomic64_t *)(ptr), \
170
(u64)(typeof((o)-(o)))(o), \
171
(u64)(typeof((n)-(n)))(n)); \
172
break; \
173
default: \
174
__cmpxchg_called_with_bad_pointer(); \
175
} \
176
__x; \
177
})
178
179
#define tas(ptr) (xchg((ptr), 1))
180
181
#endif /* __ASSEMBLY__ */
182
183
#ifndef __tilegx__
184
#include <asm/atomic_32.h>
185
#else
186
#include <asm/atomic_64.h>
187
#endif
188
189
/* Provide the appropriate atomic_long_t definitions. */
190
#ifndef __ASSEMBLY__
191
#include <asm-generic/atomic-long.h>
192
#endif
193
194
#endif /* _ASM_TILE_ATOMIC_H */
195
196