os/support: implement atomic_*() using GCC builtin helpers
If GCC knows what these functions are actually doing the resulting
code can be optimized better what is especially noticeable in case of
invocations of atomic_{or,and}() that ignore the result. Obviously,
everything is inlined what also improves performance.
Signed-off-by: Paweł Dziepak <[email protected]>
This commit is contained in:
@@ -32,6 +32,9 @@ memory_full_barrier_inline(void)
|
||||
#define memory_full_barrier memory_full_barrier_inline
|
||||
|
||||
|
||||
#if __GNUC__ < 4
|
||||
|
||||
|
||||
static inline void
|
||||
atomic_set_inline(int32* value, int32 newValue)
|
||||
{
|
||||
@@ -84,14 +87,13 @@ atomic_get_inline(int32* value)
|
||||
|
||||
#define atomic_set atomic_set_inline
|
||||
#define atomic_get_and_set atomic_get_and_set_inline
|
||||
#ifndef atomic_test_and_set
|
||||
# define atomic_test_and_set atomic_test_and_set_inline
|
||||
#endif
|
||||
#ifndef atomic_add
|
||||
# define atomic_add atomic_add_inline
|
||||
#endif
|
||||
#define atomic_test_and_set atomic_test_and_set_inline
|
||||
#define atomic_add atomic_add_inline
|
||||
#define atomic_get atomic_get_inline
|
||||
|
||||
|
||||
#endif // dark ages
|
||||
|
||||
|
||||
#endif // _KERNEL_ARCH_X86_32_ATOMIC_H
|
||||
|
||||
|
||||
@@ -31,123 +31,5 @@ memory_full_barrier_inline(void)
|
||||
#define memory_write_barrier memory_write_barrier_inline
|
||||
#define memory_full_barrier memory_full_barrier_inline
|
||||
|
||||
|
||||
static inline void
|
||||
atomic_set_inline(int32* value, int32 newValue)
|
||||
{
|
||||
memory_write_barrier();
|
||||
*(volatile int32*)value = newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_get_and_set_inline(int32* value, int32 newValue)
|
||||
{
|
||||
asm volatile("xchg %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst)
|
||||
{
|
||||
asm volatile("lock; cmpxchgl %2, (%3)"
|
||||
: "=a" (newValue)
|
||||
: "0" (testAgainst), "r" (newValue), "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_add_inline(int32* value, int32 newValue)
|
||||
{
|
||||
asm volatile("lock; xaddl %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_get_inline(int32* value)
|
||||
{
|
||||
int32 newValue = *(volatile int32*)value;
|
||||
memory_read_barrier();
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
atomic_set64_inline(int64* value, int64 newValue)
|
||||
{
|
||||
memory_write_barrier();
|
||||
*(volatile int64*)value = newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_get_and_set64_inline(int64* value, int64 newValue)
|
||||
{
|
||||
asm volatile("xchgq %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_test_and_set64_inline(int64* value, int64 newValue, int64 testAgainst)
|
||||
{
|
||||
asm volatile("lock; cmpxchgq %2, (%3)"
|
||||
: "=a" (newValue)
|
||||
: "0" (testAgainst), "r" (newValue), "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_add64_inline(int64* value, int64 newValue)
|
||||
{
|
||||
asm volatile("lock; xaddq %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_get64_inline(int64* value)
|
||||
{
|
||||
int64 newValue = *(volatile int64*)value;
|
||||
memory_read_barrier();
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
#define atomic_set atomic_set_inline
|
||||
#define atomic_get_and_set atomic_get_and_set_inline
|
||||
#ifndef atomic_test_and_set
|
||||
# define atomic_test_and_set atomic_test_and_set_inline
|
||||
#endif
|
||||
#ifndef atomic_add
|
||||
# define atomic_add atomic_add_inline
|
||||
#endif
|
||||
#define atomic_get atomic_get_inline
|
||||
|
||||
#define atomic_set64 atomic_set64_inline
|
||||
#define atomic_get_and_set64 atomic_get_and_set64_inline
|
||||
#define atomic_test_and_set64 atomic_test_and_set64_inline
|
||||
#define atomic_add64 atomic_add64_inline
|
||||
#define atomic_get64 atomic_get64_inline
|
||||
|
||||
|
||||
#endif // _KERNEL_ARCH_X86_64_ATOMIC_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user