xref: /linux/arch/x86/include/asm/atomic64_32.h (revision 8b1935e6a36b0967efc593d67ed3aebbfbc1f5b1)
1 #ifndef _ASM_X86_ATOMIC64_32_H
2 #define _ASM_X86_ATOMIC64_32_H
3 
4 #include <linux/compiler.h>
5 #include <linux/types.h>
6 #include <asm/processor.h>
7 //#include <asm/cmpxchg.h>
8 
9 /* An 64bit atomic type */
10 
11 typedef struct {
12 	u64 __aligned(8) counter;
13 } atomic64_t;
14 
15 #define ATOMIC64_INIT(val)	{ (val) }
16 
17 extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
18 
19 /**
20  * atomic64_xchg - xchg atomic64 variable
21  * @ptr:      pointer to type atomic64_t
22  * @new_val:  value to assign
23  *
24  * Atomically xchgs the value of @ptr to @new_val and returns
25  * the old value.
26  */
27 extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
28 
29 /**
30  * atomic64_set - set atomic64 variable
31  * @ptr:      pointer to type atomic64_t
32  * @new_val:  value to assign
33  *
34  * Atomically sets the value of @ptr to @new_val.
35  */
36 extern void atomic64_set(atomic64_t *ptr, u64 new_val);
37 
38 /**
39  * atomic64_read - read atomic64 variable
40  * @ptr:      pointer to type atomic64_t
41  *
42  * Atomically reads the value of @ptr and returns it.
43  */
44 static inline u64 atomic64_read(atomic64_t *ptr)
45 {
46 	u64 res;
47 
48 	/*
49 	 * Note, we inline this atomic64_t primitive because
50 	 * it only clobbers EAX/EDX and leaves the others
51 	 * untouched. We also (somewhat subtly) rely on the
52 	 * fact that cmpxchg8b returns the current 64-bit value
53 	 * of the memory location we are touching:
54 	 */
55 	asm volatile(
56 		"mov %%ebx, %%eax\n\t"
57 		"mov %%ecx, %%edx\n\t"
58 		LOCK_PREFIX "cmpxchg8b %1\n"
59 			: "=&A" (res)
60 			: "m" (*ptr)
61 		);
62 
63 	return res;
64 }
65 
66 extern u64 atomic64_read(atomic64_t *ptr);
67 
68 /**
69  * atomic64_add_return - add and return
70  * @delta: integer value to add
71  * @ptr:   pointer to type atomic64_t
72  *
73  * Atomically adds @delta to @ptr and returns @delta + *@ptr
74  */
75 extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
76 
77 /*
78  * Other variants with different arithmetic operators:
79  */
80 extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
81 extern u64 atomic64_inc_return(atomic64_t *ptr);
82 extern u64 atomic64_dec_return(atomic64_t *ptr);
83 
84 /**
85  * atomic64_add - add integer to atomic64 variable
86  * @delta: integer value to add
87  * @ptr:   pointer to type atomic64_t
88  *
89  * Atomically adds @delta to @ptr.
90  */
91 extern void atomic64_add(u64 delta, atomic64_t *ptr);
92 
93 /**
94  * atomic64_sub - subtract the atomic64 variable
95  * @delta: integer value to subtract
96  * @ptr:   pointer to type atomic64_t
97  *
98  * Atomically subtracts @delta from @ptr.
99  */
100 extern void atomic64_sub(u64 delta, atomic64_t *ptr);
101 
102 /**
103  * atomic64_sub_and_test - subtract value from variable and test result
104  * @delta: integer value to subtract
105  * @ptr:   pointer to type atomic64_t
106  *
107  * Atomically subtracts @delta from @ptr and returns
108  * true if the result is zero, or false for all
109  * other cases.
110  */
111 extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
112 
113 /**
114  * atomic64_inc - increment atomic64 variable
115  * @ptr: pointer to type atomic64_t
116  *
117  * Atomically increments @ptr by 1.
118  */
119 extern void atomic64_inc(atomic64_t *ptr);
120 
121 /**
122  * atomic64_dec - decrement atomic64 variable
123  * @ptr: pointer to type atomic64_t
124  *
125  * Atomically decrements @ptr by 1.
126  */
127 extern void atomic64_dec(atomic64_t *ptr);
128 
129 /**
130  * atomic64_dec_and_test - decrement and test
131  * @ptr: pointer to type atomic64_t
132  *
133  * Atomically decrements @ptr by 1 and
134  * returns true if the result is 0, or false for all other
135  * cases.
136  */
137 extern int atomic64_dec_and_test(atomic64_t *ptr);
138 
139 /**
140  * atomic64_inc_and_test - increment and test
141  * @ptr: pointer to type atomic64_t
142  *
143  * Atomically increments @ptr by 1
144  * and returns true if the result is zero, or false for all
145  * other cases.
146  */
147 extern int atomic64_inc_and_test(atomic64_t *ptr);
148 
149 /**
150  * atomic64_add_negative - add and test if negative
151  * @delta: integer value to add
152  * @ptr:   pointer to type atomic64_t
153  *
154  * Atomically adds @delta to @ptr and returns true
155  * if the result is negative, or false when
156  * result is greater than or equal to zero.
157  */
158 extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
159 
160 #endif /* _ASM_X86_ATOMIC64_32_H */
161