parlib: Remove get_user_ctx_stack()
[akaros.git] / user / parlib / include / parlib / x86 / atomic.h
1 #pragma once
2
3 #include <ros/atomic.h>
4
5 __BEGIN_DECLS
6
7 static inline void atomic_init(atomic_t *number, long val);
8 static inline long atomic_read(atomic_t *number);
9 static inline void atomic_set(atomic_t *number, long val);
10 static inline void atomic_inc(atomic_t *number);
11 static inline void atomic_dec(atomic_t *number);
12 static inline long atomic_fetch_and_add(atomic_t *number, long val);
13 static inline long atomic_swap(atomic_t *addr, long val);
14 static inline void *atomic_swap_ptr(void **addr, void *val);
15 static inline uint32_t atomic_swap_u32(uint32_t *addr, uint32_t val);
16 static inline bool atomic_cas(atomic_t *addr, long exp_val, long new_val);
17 static inline bool atomic_cas_ptr(void **addr, void *exp_val, void *new_val);
18 static inline bool atomic_cas_u32(uint32_t *addr, uint32_t exp_val,
19                                   uint32_t new_val);
20 static inline void atomic_andb(volatile uint8_t *number, uint8_t mask);
21 static inline void atomic_orb(volatile uint8_t *number, uint8_t mask);
22
23 /* Inlined functions declared above */
24 static inline void atomic_init(atomic_t *number, long val)
25 {
26         asm volatile("mov %1,%0" : "=m"(*number) : "r"(val));
27 }
28
29 static inline long atomic_read(atomic_t *number)
30 {
31         long val;
32         asm volatile("mov %1,%0" : "=r"(val) : "m"(*number));
33         return val;
34 }
35
36 static inline void atomic_set(atomic_t *number, long val)
37 {
38         asm volatile("mov %1,%0" : "=m"(*number) : "r"(val));
39 }
40
41 static inline void atomic_inc(atomic_t *number)
42 {
43         (void)__sync_fetch_and_add(number, 1);
44 }
45
46 static inline void atomic_dec(atomic_t *number)
47 {
48         (void)__sync_fetch_and_sub(number, 1);
49 }
50
51 static inline long atomic_fetch_and_add(atomic_t *number, long val)
52 {
53         return (long)__sync_fetch_and_add(number, val);
54 }
55
56 static inline long atomic_swap(atomic_t *addr, long val)
57 {
58         /* This poorly named function does an xchg */
59         return (long)__sync_lock_test_and_set(addr, val);
60 }
61
62 static inline void *atomic_swap_ptr(void **addr, void *val)
63 {
64         return (void*)__sync_lock_test_and_set(addr, val);
65 }
66
67 static inline uint32_t atomic_swap_u32(uint32_t *addr, uint32_t val)
68 {
69         return (uint32_t)__sync_lock_test_and_set(addr, val);
70 }
71
72 static inline bool atomic_cas(atomic_t *addr, long exp_val, long new_val)
73 {
74         return __sync_bool_compare_and_swap(addr, exp_val, new_val);
75 }
76
77 static inline bool atomic_cas_ptr(void **addr, void *exp_val, void *new_val)
78 {
79         return __sync_bool_compare_and_swap(addr, exp_val, new_val);
80 }
81
82 static inline bool atomic_cas_u32(uint32_t *addr, uint32_t exp_val,
83                                   uint32_t new_val)
84 {
85         return __sync_bool_compare_and_swap(addr, exp_val, new_val);
86 }
87
88 static inline void atomic_andb(volatile uint8_t *number, uint8_t mask)
89 {
90         (void)__sync_fetch_and_and(number, mask);
91 }
92
93 static inline void atomic_orb(volatile uint8_t *number, uint8_t mask)
94 {
95         (void)__sync_fetch_and_or(number, mask);
96 }
97
98 __END_DECLS