xref: /haiku/headers/private/kernel/arch/x86/32/atomic.h (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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 #if __GNUC__ < 4
36 
37 
38 static inline void
39 atomic_set_inline(int32* value, int32 newValue)
40 {
41 	memory_write_barrier();
42 	*(volatile int32*)value = newValue;
43 }
44 
45 
46 static inline int32
47 atomic_get_and_set_inline(int32* value, int32 newValue)
48 {
49 	asm volatile("xchgl %0, (%1)"
50 		: "+r" (newValue)
51 		: "r" (value)
52 		: "memory");
53 	return newValue;
54 }
55 
56 
57 static inline int32
58 atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst)
59 {
60 	asm volatile("lock; cmpxchgl %2, (%3)"
61 		: "=a" (newValue)
62 		: "0" (testAgainst), "r" (newValue), "r" (value)
63 		: "memory");
64 	return newValue;
65 }
66 
67 
68 static inline int32
69 atomic_add_inline(int32* value, int32 newValue)
70 {
71 	asm volatile("lock; xaddl %0, (%1)"
72 		: "+r" (newValue)
73 		: "r" (value)
74 		: "memory");
75 	return newValue;
76 }
77 
78 
79 static inline int32
80 atomic_get_inline(int32* value)
81 {
82 	int32 newValue = *(volatile int32*)value;
83 	memory_read_barrier();
84 	return newValue;
85 }
86 
87 
88 #define atomic_set				atomic_set_inline
89 #define atomic_get_and_set		atomic_get_and_set_inline
90 #define atomic_test_and_set		atomic_test_and_set_inline
91 #define atomic_add				atomic_add_inline
92 #define atomic_get				atomic_get_inline
93 
94 
95 #endif	// dark ages
96 
97 
98 #endif	// _KERNEL_ARCH_X86_32_ATOMIC_H
99 
100