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