2828#include <ktf.h>
2929#include <lib.h>
3030
31+ typedef struct {
32+ int32_t counter ;
33+ } atomic_t ;
34+
35+ typedef struct {
36+ int64_t counter ;
37+ } atomic64_t ;
38+
39+ #define ATOMIC_INIT (i ) \
40+ { (i) }
41+
42+ #define atomic_set (v , i ) (ACCESS_ONCE((v)->counter) = (i))
43+ #define atomic_read (v ) (ACCESS_ONCE((v)->counter))
44+
3145/* Static declarations */
3246
33- static inline bool test_bit (unsigned int bit , volatile void * addr ) {
47+ static inline bool atomic_test_bit (unsigned int bit , volatile void * addr ) {
3448 bool status ;
3549
3650 asm volatile ("bt %[bit], %[addr];"
@@ -42,7 +56,7 @@ static inline bool test_bit(unsigned int bit, volatile void *addr) {
4256 return status ;
4357}
4458
45- static inline bool test_and_set_bit (unsigned int bit , volatile void * addr ) {
59+ static inline bool atomic_test_and_set_bit (unsigned int bit , volatile void * addr ) {
4660 bool status ;
4761
4862 asm volatile ("lock bts %[bit], %[addr];"
@@ -54,7 +68,7 @@ static inline bool test_and_set_bit(unsigned int bit, volatile void *addr) {
5468 return status ;
5569}
5670
57- static inline bool test_and_reset_bit (unsigned int bit , volatile void * addr ) {
71+ static inline bool atomic_test_and_reset_bit (unsigned int bit , volatile void * addr ) {
5872 bool status ;
5973
6074 asm volatile ("lock btr %[bit], %[addr];"
@@ -66,7 +80,7 @@ static inline bool test_and_reset_bit(unsigned int bit, volatile void *addr) {
6680 return status ;
6781}
6882
69- static inline bool test_and_complement_bit (unsigned int bit , volatile void * addr ) {
83+ static inline bool atomic_test_and_complement_bit (unsigned int bit , volatile void * addr ) {
7084 bool status ;
7185
7286 asm volatile ("lock btc %[bit], %[addr];"
@@ -78,6 +92,108 @@ static inline bool test_and_complement_bit(unsigned int bit, volatile void *addr
7892 return status ;
7993}
8094
95+ static inline void atomic_inc (atomic_t * v ) {
96+ asm volatile ("lock incl %[addr];" : : [ addr ] "m" (v -> counter ) : "memory" );
97+ }
98+
99+ static inline void atomic64_inc (atomic64_t * v ) {
100+ asm volatile ("lock incq %[addr];" : : [ addr ] "m" (v -> counter ) : "memory" );
101+ }
102+
103+ static inline int32_t atomic_add_return (atomic_t * v , int32_t n ) {
104+ int32_t val = n ;
105+ asm volatile ("lock xaddl %[n], %[addr];"
106+ : [ n ] "+r" (val ), [ addr ] "+m" (v -> counter )
107+ :
108+ : "memory" );
109+ return val ;
110+ }
111+
112+ static inline int64_t atomic64_add_return (atomic64_t * v , int64_t n ) {
113+ int64_t val = n ;
114+ asm volatile ("lock xaddq %[n], %[addr];"
115+ : [ n ] "+r" (val ), [ addr ] "+m" (v -> counter )
116+ :
117+ : "memory" );
118+ return val ;
119+ }
120+
121+ static inline int32_t atomic_inc_return (atomic_t * v ) { return atomic_add_return (v , 1 ); }
122+
123+ static inline int64_t atomic64_inc_return (atomic64_t * v ) {
124+ return atomic64_add_return (v , 1 );
125+ }
126+
127+ static inline int atomic_inc_and_test (atomic_t * v ) {
128+ uint8_t c ;
129+ asm volatile ("lock incl %[addr]; sete %[c]"
130+ : [ addr ] "=m" (v -> counter ), [ c ] "=r" (c )
131+ :
132+ : "memory" );
133+ return c != 0 ;
134+ }
135+
136+ static inline int atomic64_inc_and_test (atomic64_t * v ) {
137+ uint8_t c ;
138+ asm volatile ("lock incq %[addr]; sete %[c]"
139+ : [ addr ] "=m" (v -> counter ), [ c ] "=r" (c )
140+ :
141+ : "memory" );
142+ return c != 0 ;
143+ }
144+
145+ static inline void atomic_dec (atomic_t * v ) {
146+ asm volatile ("lock decl %[addr];" : : [ addr ] "m" (v -> counter ) : "memory" );
147+ }
148+
149+ static inline void atomic64_dec (atomic64_t * v ) {
150+ asm volatile ("lock decq %[addr];" : : [ addr ] "m" (v -> counter ) : "memory" );
151+ }
152+
153+ static inline int32_t atomic_sub_return (atomic_t * v , int32_t n ) {
154+ int32_t val = n ;
155+ asm volatile ("lock xsubl %[n], %[addr];"
156+ : [ n ] "+r" (val ), [ addr ] "+m" (v -> counter )
157+ :
158+ : "memory" );
159+ return val ;
160+ }
161+
162+ static inline int64_t atomic64_sub_return (atomic64_t * v , int64_t n ) {
163+ int64_t val = n ;
164+ asm volatile ("lock xsubq %[n], %[addr];"
165+ : [ n ] "+r" (val ), [ addr ] "+m" (v -> counter )
166+ :
167+ : "memory" );
168+ return val ;
169+ }
170+
171+ static inline int32_t atomic_dec_return (atomic_t * v , int32_t n ) {
172+ return atomic_sub_return (v , 1 );
173+ }
174+
175+ static inline int64_t atomic64_dec_return (atomic64_t * v , int64_t n ) {
176+ return atomic64_sub_return (v , 1 );
177+ }
178+
179+ static inline int atomic_dec_and_test (atomic_t * v ) {
180+ uint8_t c ;
181+ asm volatile ("lock decl %[addr]; sete %[c]"
182+ : [ addr ] "=m" (v -> counter ), [ c ] "=r" (c )
183+ :
184+ : "memory" );
185+ return c != 0 ;
186+ }
187+
188+ static inline int atomic64_dec_and_test (atomic64_t * v ) {
189+ uint8_t c ;
190+ asm volatile ("lock decq %[addr]; sete %[c]"
191+ : [ addr ] "=m" (v -> counter ), [ c ] "=r" (c )
192+ :
193+ : "memory" );
194+ return c != 0 ;
195+ }
196+
81197/* External declarations */
82198
83199#endif /* KTF_ATOMIC_H */
0 commit comments