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