1 #ifndef _LINUX_ATOMIC_H
2 #define _LINUX_ATOMIC_H
3
4 #include <linux/types.h>
5
6 //
7 // atomic
8 //
9
10 typedef struct {
11 volatile LONG counter;
12 } atomic_t;
13
14 #define ATOMIC_INIT(i) (i)
15
16 /**
17 * atomic_read - read atomic variable
18 * @v: pointer of type atomic_t
19 *
20 * Atomically reads the value of @v. Note that the guaranteed
21 * useful range of an atomic_t is only 24 bits.
22 */
23 #define atomic_read(v) ((v)->counter)
24
25 /**
26 * atomic_set - set atomic variable
27 * @v: pointer of type atomic_t
28 * @i: required value
29 *
30 * Atomically sets the value of @v to @i. Note that the guaranteed
31 * useful range of an atomic_t is only 24 bits.
32 */
33 #define atomic_set(v,i) InterlockedExchange((PLONG)(&(v)->counter), (LONG)(i))
34
35 /**
36 * atomic_add - add integer to atomic variable
37 * @i: integer value to add
38 * @v: pointer of type atomic_t
39 *
40 * Atomically adds @i to @v. Note that the guaranteed useful range
41 * of an atomic_t is only 24 bits.
42 */
atomic_add(int volatile i,atomic_t volatile * v)43 static inline void atomic_add(int volatile i, atomic_t volatile *v)
44 {
45 InterlockedExchangeAdd((PLONG)(&v->counter), (LONG) i);
46 }
47
48 /**
49 * atomic_sub - subtract the atomic variable
50 * @i: integer value to subtract
51 * @v: pointer of type atomic_t
52 *
53 * Atomically subtracts @i from @v. Note that the guaranteed
54 * useful range of an atomic_t is only 24 bits.
55 */
atomic_sub(int volatile i,atomic_t volatile * v)56 static inline void atomic_sub(int volatile i, atomic_t volatile *v)
57 {
58 InterlockedExchangeAdd((PLONG)(&v->counter), (LONG) (-1*i));
59 }
60
61 /**
62 * atomic_sub_and_test - subtract value from variable and test result
63 * @i: integer value to subtract
64 * @v: pointer of type atomic_t
65 *
66 * Atomically subtracts @i from @v and returns
67 * true if the result is zero, or false for all
68 * other cases. Note that the guaranteed
69 * useful range of an atomic_t is only 24 bits.
70 */
atomic_sub_and_test(int volatile i,atomic_t volatile * v)71 static inline int atomic_sub_and_test(int volatile i, atomic_t volatile *v)
72 {
73 int counter, result;
74
75 do {
76
77 counter = v->counter;
78 result = counter - i;
79
80 } while ( InterlockedCompareExchange(
81 (PLONG) (&v->counter),
82 (LONG) result,
83 (LONG) counter) != counter);
84
85 return (result == 0);
86 }
87
88 /**
89 * atomic_inc - increment atomic variable
90 * @v: pointer of type atomic_t
91 *
92 * Atomically increments @v by 1. Note that the guaranteed
93 * useful range of an atomic_t is only 24 bits.
94 */
atomic_inc(atomic_t volatile * v)95 static inline void atomic_inc(atomic_t volatile *v)
96 {
97 InterlockedIncrement((PLONG)(&v->counter));
98 }
99
100 /**
101 * atomic_dec - decrement atomic variable
102 * @v: pointer of type atomic_t
103 *
104 * Atomically decrements @v by 1. Note that the guaranteed
105 * useful range of an atomic_t is only 24 bits.
106 */
atomic_dec(atomic_t volatile * v)107 static inline void atomic_dec(atomic_t volatile *v)
108 {
109 InterlockedDecrement((PLONG)(&v->counter));
110 }
111
112 /**
113 * atomic_dec_and_test - decrement and test
114 * @v: pointer of type atomic_t
115 *
116 * Atomically decrements @v by 1 and
117 * returns true if the result is 0, or false for all other
118 * cases. Note that the guaranteed
119 * useful range of an atomic_t is only 24 bits.
120 */
atomic_dec_and_test(atomic_t volatile * v)121 static inline int atomic_dec_and_test(atomic_t volatile *v)
122 {
123 return (0 == InterlockedDecrement((PLONG)(&v->counter)));
124 }
125
126 /**
127 * atomic_inc_and_test - increment and test
128 * @v: pointer of type atomic_t
129 *
130 * Atomically increments @v by 1
131 * and returns true if the result is zero, or false for all
132 * other cases. Note that the guaranteed
133 * useful range of an atomic_t is only 24 bits.
134 */
atomic_inc_and_test(atomic_t volatile * v)135 static inline int atomic_inc_and_test(atomic_t volatile *v)
136 {
137 return (0 == InterlockedIncrement((PLONG)(&v->counter)));
138 }
139
140 /**
141 * atomic_add_negative - add and test if negative
142 * @v: pointer of type atomic_t
143 * @i: integer value to add
144 *
145 * Atomically adds @i to @v and returns true
146 * if the result is negative, or false when
147 * result is greater than or equal to zero. Note that the guaranteed
148 * useful range of an atomic_t is only 24 bits.
149 */
atomic_add_negative(int volatile i,atomic_t volatile * v)150 static inline int atomic_add_negative(int volatile i, atomic_t volatile *v)
151 {
152 return (InterlockedExchangeAdd((PLONG)(&v->counter), (LONG) i) + i);
153 }
154
155 #endif /* LINUX_ATOMIC_H */
156