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