xref: /haiku/headers/private/kernel/arch/x86/32/atomic.h (revision 720423579387710769ce1018cd78417098e305c6)
1 /*
2  * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _KERNEL_ARCH_X86_32_ATOMIC_H
6 #define _KERNEL_ARCH_X86_32_ATOMIC_H
7 
8 
9 static inline void
10 memory_read_barrier_inline(void)
11 {
12 	asm volatile("lock; addl $0, (%%esp)" : : : "memory");
13 }
14 
15 
16 static inline void
17 memory_write_barrier_inline(void)
18 {
19 	asm volatile("lock; addl $0, (%%esp)" : : : "memory");
20 }
21 
22 
23 static inline void
24 memory_full_barrier_inline(void)
25 {
26 	asm volatile("lock; addl $0, (%%esp)" : : : "memory");
27 }
28 
29 
30 #define memory_read_barrier		memory_read_barrier_inline
31 #define memory_write_barrier	memory_write_barrier_inline
32 #define memory_full_barrier		memory_full_barrier_inline
33 
34 
35 static inline void
36 atomic_set_inline(int32* value, int32 newValue)
37 {
38 	memory_write_barrier();
39 	*(volatile int32*)value = newValue;
40 }
41 
42 
43 static inline int32
44 atomic_get_and_set_inline(int32* value, int32 newValue)
45 {
46 	asm volatile("xchgl %0, (%1)"
47 		: "+r" (newValue)
48 		: "r" (value)
49 		: "memory");
50 	return newValue;
51 }
52 
53 
54 static inline int32
55 atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst)
56 {
57 	asm volatile("lock; cmpxchgl %2, (%3)"
58 		: "=a" (newValue)
59 		: "0" (testAgainst), "r" (newValue), "r" (value)
60 		: "memory");
61 	return newValue;
62 }
63 
64 
65 static inline int32
66 atomic_add_inline(int32* value, int32 newValue)
67 {
68 	asm volatile("lock; xaddl %0, (%1)"
69 		: "+r" (newValue)
70 		: "r" (value)
71 		: "memory");
72 	return newValue;
73 }
74 
75 
76 static inline int32
77 atomic_get_inline(int32* value)
78 {
79 	int32 newValue = *(volatile int32*)value;
80 	memory_read_barrier();
81 	return newValue;
82 }
83 
84 
85 #define atomic_set				atomic_set_inline
86 #define atomic_get_and_set		atomic_get_and_set_inline
87 #ifndef atomic_test_and_set
88 #	define atomic_test_and_set	atomic_test_and_set_inline
89 #endif
90 #ifndef atomic_add
91 #	define atomic_add			atomic_add_inline
92 #endif
93 #define atomic_get				atomic_get_inline
94 
95 
96 #endif	// _KERNEL_ARCH_X86_32_ATOMIC_H
97 
98