Skip to content

Commit 80c08fc

Browse files
82marbagwipawel
authored andcommitted
atomic: basic atomic operations
Signed-off-by: Daniele Ahmed <ahmeddan amazon c;om>
1 parent 288ee4f commit 80c08fc

File tree

2 files changed

+122
-6
lines changed

2 files changed

+122
-6
lines changed

include/arch/x86/atomic.h

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,23 @@
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 */

include/spinlock.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ typedef volatile unsigned int spinlock_t;
3939

4040
static inline void spin_lock(spinlock_t *lock) {
4141
ASSERT(lock);
42-
while (test_and_set_bit(LOCK_BIT, lock))
42+
while (atomic_test_and_set_bit(LOCK_BIT, lock))
4343
cpu_relax();
4444
}
4545

4646
static inline void spin_unlock(spinlock_t *lock) {
4747
ASSERT(lock);
48-
test_and_reset_bit(LOCK_BIT, lock);
48+
atomic_test_and_reset_bit(LOCK_BIT, lock);
4949
}
5050

5151
/* External declarations */

0 commit comments

Comments
 (0)