hrev47741 adds 6 changesets to branch 'master' old head: ae18461ec1ad87c67a29310349b47ffd17f475f2 new head: 721a07ac24df63af87afd8d52f5e08ec6566c9e0 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=721a07a+%5Eae18461 ---------------------------------------------------------------------------- 54b314f: add-ons/kernel: add casts when calling atomic_*() Soon GCC is going to be a bit stricter about the type of pointer passed to atomic_*() functions. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> 2e2c9bd: 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 <pdziepak@xxxxxxxxxxx> aa58f7e: os/arch: implement all atomic_*() using std::atomic<> Time to get rid of some asm code. Surprisingly, it appears that on x86[_64] the emitted code for atomic_test_and_get() isn't as efficient as it could be, even with -O2, but cmpxchg is so expensive that this slight difference shouldn't matter much. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> d3b1caa: kernel, libroot: use C++11 atomics in atomic_*() The less assembler in our sources the better. These functions wouldn't be used very much since SupportDef.h inlines them, but the symbols should be available. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> a4cdc60: build: remove B_USE_BUILTIN_ATOMIC_FUNCTIONS No reason not to use GCC atomic support on non-x86 archs. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> 721a07a: libroot: remove ATOMIC_FUNCS_ARE_SYSCALLS GCC knows whether these functions need to be implemented using syscalls (or more clever solutions like in Linux) and calls libgcc in such case. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> [ Paweł Dziepak <pdziepak@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- 16 files changed, 268 insertions(+), 431 deletions(-) headers/os/support/SupportDefs.h | 158 +++++++++++++++---- headers/private/kernel/arch/x86/32/atomic.h | 14 +- headers/private/kernel/arch/x86/64/atomic.h | 118 -------------- src/add-ons/kernel/busses/ata/ide_isa/ide_isa.c | 2 +- .../drivers/disk/floppy/pc_floppy/floppy.c | 2 +- src/build/libroot/atomic.cpp | 6 + src/system/boot/Jamfile | 7 +- src/system/kernel/lib/arch/arm/Jamfile | 1 - src/system/kernel/lib/arch/x86_64/Jamfile | 3 +- src/system/libroot/os/arch/arm/Jamfile | 1 - src/system/libroot/os/arch/arm/atomic.S | 113 ------------- .../libroot/os/arch/generic/generic_atomic.cpp | 114 ++++++++++++- src/system/libroot/os/arch/x86_64/Jamfile | 5 +- src/system/libroot/os/arch/x86_64/atomic.S | 153 ------------------ src/system/runtime_loader/arch/arm/Jamfile | 1 - src/system/runtime_loader/arch/x86_64/Jamfile | 1 - ############################################################################ Commit: 54b314f15fa73d8e8c8425c4490d82b13754f364 URL: http://cgit.haiku-os.org/haiku/commit/?id=54b314f Author: Paweł Dziepak <pdziepak@xxxxxxxxxxx> Date: Mon Aug 25 12:54:24 2014 UTC add-ons/kernel: add casts when calling atomic_*() Soon GCC is going to be a bit stricter about the type of pointer passed to atomic_*() functions. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/busses/ata/ide_isa/ide_isa.c b/src/add-ons/kernel/busses/ata/ide_isa/ide_isa.c index 591d764..80e1d40 100644 --- a/src/add-ons/kernel/busses/ata/ide_isa/ide_isa.c +++ b/src/add-ons/kernel/busses/ata/ide_isa/ide_isa.c @@ -409,7 +409,7 @@ channel_removed(void *cookie) TRACE("channel_removed()\n"); // disable access instantly - atomic_or(&channel->lost, 1); + atomic_or((int32*)&channel->lost, 1); } diff --git a/src/add-ons/kernel/drivers/disk/floppy/pc_floppy/floppy.c b/src/add-ons/kernel/drivers/disk/floppy/pc_floppy/floppy.c index b78cda2..90e29d2 100644 --- a/src/add-ons/kernel/drivers/disk/floppy/pc_floppy/floppy.c +++ b/src/add-ons/kernel/drivers/disk/floppy/pc_floppy/floppy.c @@ -545,7 +545,7 @@ motor_off_daemon(void *t, int tim) for (i = 0; i < MAX_FLOPPIES; i++) { if (floppies[i].iobase && !floppies[i].pending_cmd && floppies[i].motor_timeout > 0) { TRACE("floppies[%d].motor_timeout = %ld\n", i, floppies[i].motor_timeout); - if (atomic_add(&floppies[i].motor_timeout, -500000) <= 500000) { + if (atomic_add((int32*)&floppies[i].motor_timeout, -500000) <= 500000) { dprintf("turning off motor for drive %d\n", floppies[i].drive_num); turn_off_motor(&floppies[i]); floppies[i].motor_timeout = 0; ############################################################################ Commit: 2e2c9bd3d058dac3609103ca67011eaee14e9333 URL: http://cgit.haiku-os.org/haiku/commit/?id=2e2c9bd Author: Paweł Dziepak <pdziepak@xxxxxxxxxxx> Date: Mon Aug 25 12:55:55 2014 UTC 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 <pdziepak@xxxxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/headers/os/support/SupportDefs.h b/headers/os/support/SupportDefs.h index 1f413d3..b863334 100644 --- a/headers/os/support/SupportDefs.h +++ b/headers/os/support/SupportDefs.h @@ -195,23 +195,6 @@ extern const char *B_EMPTY_STRING; extern "C" { #endif -/* Atomic functions; previous value is returned */ -extern void atomic_set(int32* value, int32 newValue); -extern int32 atomic_get_and_set(int32* value, int32 newValue); -extern int32 atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst); -extern int32 atomic_add(int32 *value, int32 addValue); -extern int32 atomic_and(int32 *value, int32 andValue); -extern int32 atomic_or(int32 *value, int32 orValue); -extern int32 atomic_get(int32 *value); - -extern void atomic_set64(int64* value, int64 newValue); -extern int64 atomic_get_and_set64(int64* value, int64 newValue); -extern int64 atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst); -extern int64 atomic_add64(int64 *value, int64 addValue); -extern int64 atomic_and64(int64 *value, int64 andValue); -extern int64 atomic_or64(int64 *value, int64 orValue); -extern int64 atomic_get64(int64 *value); - /* Other stuff */ extern void* get_stack_frame(void); @@ -232,18 +215,141 @@ extern void* get_stack_frame(void); /* Use the built-in atomic functions, if requested and available. */ -#if defined(B_USE_BUILTIN_ATOMIC_FUNCTIONS) && __GNUC__ >= 4 +#if defined(B_USE_BUILTIN_ATOMIC_FUNCTIONS) && __GNUC__ > 4 \ + || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) + + +static inline void +atomic_set(int32* value, int32 newValue) +{ + __atomic_store_n(value, newValue, __ATOMIC_RELEASE); +} + + +static inline int32 +atomic_get_and_set(int32* value, int32 newValue) +{ + return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST); +} + + +static inline int32 +atomic_test_and_set(int32* value, int32 newValue, int32 testAgainst) +{ + __atomic_compare_exchange_n(value, &testAgainst, newValue, 1, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return testAgainst; +} + + +static inline int32 +atomic_add(int32* value, int32 addValue) +{ + return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST); +} + + +static inline int32 +atomic_and(int32* value, int32 andValue) +{ + return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST); +} + + +static inline int32 +atomic_or(int32* value, int32 orValue) +{ + return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST); +} + + +static inline int32 +atomic_get(int32* value) +{ + return __atomic_load_n(value, __ATOMIC_ACQUIRE); +} + + +static inline void +atomic_set64(int64* value, int64 newValue) +{ + __atomic_store_n(value, newValue, __ATOMIC_RELEASE); +} + + +static inline int64 +atomic_get_and_set64(int64* value, int64 newValue) +{ + return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST); +} + + +static inline int64 +atomic_test_and_set64(int64* value, int64 newValue, int64 testAgainst) +{ + __atomic_compare_exchange_n(value, &testAgainst, newValue, 1, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return testAgainst; +} + + +static inline int64 +atomic_add64(int64* value, int64 addValue) +{ + return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST); +} + + +static inline int64 +atomic_and64(int64* value, int64 andValue) +{ + return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST); +} + -#define atomic_test_and_set(valuePointer, newValue, testAgainst) \ - __sync_val_compare_and_swap(valuePointer, testAgainst, newValue) -#define atomic_add(valuePointer, addValue) \ - __sync_fetch_and_add(valuePointer, addValue) -#define atomic_and(valuePointer, andValue) \ - __sync_fetch_and_and(valuePointer, andValue) -#define atomic_or(valuePointer, orValue) \ - __sync_fetch_and_or(valuePointer, orValue) +static inline int64 +atomic_or64(int64* value, int64 orValue) +{ + return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST); +} + + +static inline int64 +atomic_get64(int64* value) +{ + return __atomic_load_n(value, __ATOMIC_ACQUIRE); +} + + +#else // B_USE_BUILTIN_ATOMIC_FUNCTIONS && __GNUC__ > 4 + // || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) -#endif // B_USE_BUILTIN_ATOMIC_FUNCTIONS && __GNUC__ >= 4 +#ifdef __cplusplus +extern "C" { +#endif + +/* Atomic functions; previous value is returned */ +extern void atomic_set(int32* value, int32 newValue); +extern int32 atomic_get_and_set(int32* value, int32 newValue); +extern int32 atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst); +extern int32 atomic_add(int32 *value, int32 addValue); +extern int32 atomic_and(int32 *value, int32 andValue); +extern int32 atomic_or(int32 *value, int32 orValue); +extern int32 atomic_get(int32 *value); + +extern void atomic_set64(int64* value, int64 newValue); +extern int64 atomic_get_and_set64(int64* value, int64 newValue); +extern int64 atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst); +extern int64 atomic_add64(int64 *value, int64 addValue); +extern int64 atomic_and64(int64 *value, int64 andValue); +extern int64 atomic_or64(int64 *value, int64 orValue); +extern int64 atomic_get64(int64 *value); + +#ifdef __cplusplus +} +#endif + +#endif #endif /* _SUPPORT_DEFS_H */ diff --git a/headers/private/kernel/arch/x86/32/atomic.h b/headers/private/kernel/arch/x86/32/atomic.h index adec9c0..eb2996c 100644 --- a/headers/private/kernel/arch/x86/32/atomic.h +++ b/headers/private/kernel/arch/x86/32/atomic.h @@ -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 diff --git a/headers/private/kernel/arch/x86/64/atomic.h b/headers/private/kernel/arch/x86/64/atomic.h index fd56731..ed3245e 100644 --- a/headers/private/kernel/arch/x86/64/atomic.h +++ b/headers/private/kernel/arch/x86/64/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 diff --git a/src/build/libroot/atomic.cpp b/src/build/libroot/atomic.cpp index 38aed02..0e1fed4 100644 --- a/src/build/libroot/atomic.cpp +++ b/src/build/libroot/atomic.cpp @@ -6,6 +6,9 @@ #include <SupportDefs.h> +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) + + void atomic_set(int32 *value, int32 newValue) { @@ -120,3 +123,6 @@ atomic_get64(int64 *value) return *value; } + +#endif // __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) + ############################################################################ Commit: aa58f7e431a5b295d9d83c59418d97bec7180fa8 URL: http://cgit.haiku-os.org/haiku/commit/?id=aa58f7e Author: Paweł Dziepak <pdziepak@xxxxxxxxxxx> Date: Mon Aug 25 13:01:44 2014 UTC os/arch: implement all atomic_*() using std::atomic<> Time to get rid of some asm code. Surprisingly, it appears that on x86[_64] the emitted code for atomic_test_and_get() isn't as efficient as it could be, even with -O2, but cmpxchg is so expensive that this slight difference shouldn't matter much. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/src/system/libroot/os/arch/generic/generic_atomic.cpp b/src/system/libroot/os/arch/generic/generic_atomic.cpp index 73b5c56..dce3a5b 100644 --- a/src/system/libroot/os/arch/generic/generic_atomic.cpp +++ b/src/system/libroot/os/arch/generic/generic_atomic.cpp @@ -9,11 +9,119 @@ #ifndef ATOMIC_FUNCS_ARE_SYSCALLS -extern "C" int32_t + +extern "C" [[gnu::optimize("omit-frame-pointer")]] void +atomic_set(int32_t* ptr, int32_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); + obj.store(value, std::memory_order_release); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int32_t atomic_get_and_set(int32_t* ptr, int32_t value) { - auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); - return obj.exchange(value); + auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); + return obj.exchange(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int32_t +atomic_test_and_set(int32_t* ptr, int32_t desired, int32_t expected) +{ + auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); + obj.compare_exchange_strong(expected, desired); + return expected; +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int32_t +atomic_add(int32_t* ptr, int32_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); + return obj.fetch_add(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int32_t +atomic_and(int32_t* ptr, int32_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); + return obj.fetch_and(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int32_t +atomic_or(int32_t* ptr, int32_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); + return obj.fetch_or(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int32_t +atomic_get(int32_t* ptr) +{ + auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr); + return obj.load(std::memory_order_acquire); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] void +atomic_set64(int64_t* ptr, int64_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int64_t>*>(ptr); + obj.store(value, std::memory_order_release); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t +atomic_get_and_set64(int64_t* ptr, int64_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int64_t>*>(ptr); + return obj.exchange(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t +atomic_test_and_set64(int64_t* ptr, int64_t desired, int64_t expected) +{ + auto& obj = *reinterpret_cast<std::atomic<int64_t>*>(ptr); + obj.compare_exchange_strong(expected, desired); + return expected; +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t +atomic_add64(int64_t* ptr, int64_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int64_t>*>(ptr); + return obj.fetch_add(value); } + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t +atomic_and64(int64_t* ptr, int64_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int64_t>*>(ptr); + return obj.fetch_and(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t +atomic_or64(int64_t* ptr, int64_t value) +{ + auto& obj = *reinterpret_cast<std::atomic<int64_t>*>(ptr); + return obj.fetch_or(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t +atomic_get64(int64_t* ptr) +{ + auto& obj = *reinterpret_cast<std::atomic<int64_t>*>(ptr); + return obj.load(std::memory_order_acquire); +} + + #endif /* ATOMIC64_FUNCS_ARE_SYSCALLS */ ############################################################################ Commit: d3b1caa62d83444c7c95a73cdc2094d2087fb818 URL: http://cgit.haiku-os.org/haiku/commit/?id=d3b1caa Author: Paweł Dziepak <pdziepak@xxxxxxxxxxx> Date: Mon Aug 25 13:05:00 2014 UTC kernel, libroot: use C++11 atomics in atomic_*() The less assembler in our sources the better. These functions wouldn't be used very much since SupportDef.h inlines them, but the symbols should be available. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/src/system/boot/Jamfile b/src/system/boot/Jamfile index 46aecb6..4070d0e 100644 --- a/src/system/boot/Jamfile +++ b/src/system/boot/Jamfile @@ -11,9 +11,13 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) kernel lib ] ; UsePrivateHeaders [ FDirName libroot locale ] ; +local extraSources = ; +if $(TARGET_GCC_VERSION_$(TARGET_PACKAGING_ARCH)[1]) = 2 { + extraSources += atomic.S ; +} + BootMergeObject boot_libroot.o : abs.c - atomic.S ctype.cpp LocaleData.cpp qsort.c @@ -36,6 +40,7 @@ BootMergeObject boot_libroot.o : strchr.c strrchr.c strtol.c + $(extraSources) : -fno-pic ; diff --git a/src/system/kernel/lib/arch/arm/Jamfile b/src/system/kernel/lib/arch/arm/Jamfile index 12b8c50..2b7c1cc 100644 --- a/src/system/kernel/lib/arch/arm/Jamfile +++ b/src/system/kernel/lib/arch/arm/Jamfile @@ -9,7 +9,6 @@ SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ; SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ; KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o : - atomic.S byteorder.S generic_atomic.cpp diff --git a/src/system/kernel/lib/arch/x86_64/Jamfile b/src/system/kernel/lib/arch/x86_64/Jamfile index 259708b..168f14c 100644 --- a/src/system/kernel/lib/arch/x86_64/Jamfile +++ b/src/system/kernel/lib/arch/x86_64/Jamfile @@ -10,13 +10,14 @@ local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ; local posixSources = [ FDirName $(librootSources) posix ] ; SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ; +SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ; KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o : - atomic.S byteorder.S system_time_asm.S system_time.c + generic_atomic.cpp : $(TARGET_KERNEL_PIC_CCFLAGS) ; diff --git a/src/system/libroot/os/arch/arm/Jamfile b/src/system/libroot/os/arch/arm/Jamfile index 87acdea..d22221b 100644 --- a/src/system/libroot/os/arch/arm/Jamfile +++ b/src/system/libroot/os/arch/arm/Jamfile @@ -11,7 +11,6 @@ for architectureObject in [ MultiArchSubDirSetup arm ] { SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; MergeObject <$(architecture)>os_arch_$(TARGET_ARCH).o : - atomic.S byteorder.S system_time.c stack_frame.c diff --git a/src/system/libroot/os/arch/arm/atomic.S b/src/system/libroot/os/arch/arm/atomic.S deleted file mode 100644 index 56f1c2c..0000000 --- a/src/system/libroot/os/arch/arm/atomic.S +++ /dev/null @@ -1,113 +0,0 @@ -/* -** Copyright 2003, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ - -#include <asm_defs.h> -#include <arch_config.h> - - -.text - -#ifndef ATOMIC_FUNCS_ARE_SYSCALLS - -/* int atomic_add(int *value, int increment) - */ -FUNCTION(atomic_add): -miss1: ldrex r12, [r0] - add r2, r12, r1 - strex r3, r2, [r0] - teq r3, #0 - bne miss1 - mov r0, r12 - bx lr -FUNCTION_END(atomic_add) - -/* int atomic_and(int *value, int andValue) - */ -FUNCTION(atomic_and): -miss2: ldrex r12, [r0] - and r2, r12, r1 - strex r3, r2, [r0] - teq r3, #0 - bne miss2 - mov r0, r12 - bx lr -FUNCTION_END(atomic_and) - -/* int atomic_or(int *value, int orValue) - */ -FUNCTION(atomic_or): -miss3: ldrex r12, [r0] - eor r2, r12, r1 - strex r3, r2, [r0] - teq r3, #0 - bne miss3 - mov r0, r12 - bx lr -FUNCTION_END(atomic_or) - -/* void atomic_set(int *value, int setTo) - */ -FUNCTION(atomic_set): - str r1, [r0] - bx lr -FUNCTION_END(atomic_set) - -/* int atomic_test_and_set(int *value, int setTo, int testValue) - */ -FUNCTION(atomic_test_and_set): -miss5: ldrex r12, [r0] @ load from the address and mark it exclusive - cmp r12, r2 @ compare the value with the comperand(r2) - strexeq r3, r1, [r0] @ if they were equal, attempt to store the new value (r1) - bne differ @ if they were not equal jump to (differ) which clears the exclusive tag on the address and returns< - cmp r3, #1 @ check the status of the store (returned in r3) - beq miss5 @ go back to the start if it failed (0=success, 1=failure) - bne same @ if it succeeded, jump to (same) and return. there is no need to clrex if strex succeeded -differ: clrex @ clrex -same: mov r0, r12 - bx lr -FUNCTION_END(atomic_test_and_set) - -/* int atomic_get(int *value) - */ -FUNCTION(atomic_get): - ldr r0, [r0] - bx lr -FUNCTION_END(atomic_get) - -#endif /* ATOMIC_FUNCS_ARE_SYSCALLS */ - -#ifndef ATOMIC64_FUNCS_ARE_SYSCALLS - -/* int64 atomic_add64(vint64 *value, int64 addValue) */ -FUNCTION(atomic_add64): - bx lr -FUNCTION_END(atomic_add64) - -/* int64 atomic_and64(vint64 *value, int64 andValue) */ -FUNCTION(atomic_and64): - bx lr -FUNCTION_END(atomic_and64) - -/* int64 atomic_or64(vint64 *value, int64 orValue) */ -FUNCTION(atomic_or64): - bx lr -FUNCTION_END(atomic_or64) - -/* int64 atomic_set64(vint64 *value, int64 newValue) */ -FUNCTION(atomic_set64): - bx lr -FUNCTION_END(atomic_set64) - -/* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */ -FUNCTION(atomic_test_and_set64): - bx lr -FUNCTION_END(atomic_test_and_set64) - -/* int64 atomic_get64(vint64 *value) */ -FUNCTION(atomic_get64): - bx lr -FUNCTION_END(atomic_get64) - -#endif /* ATOMIC64_FUNCS_ARE_SYSCALLS */ diff --git a/src/system/libroot/os/arch/x86_64/Jamfile b/src/system/libroot/os/arch/x86_64/Jamfile index 26b8c27..5aad005 100644 --- a/src/system/libroot/os/arch/x86_64/Jamfile +++ b/src/system/libroot/os/arch/x86_64/Jamfile @@ -12,8 +12,9 @@ for architectureObject in [ MultiArchSubDirSetup x86_64 ] { # TODO in time.c! UsePrivateSystemHeaders ; + SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; + MergeObject <$(architecture)>os_arch_$(TARGET_ARCH).o : - atomic.S byteorder.S get_stack_frame.S system_info.cpp @@ -21,6 +22,8 @@ for architectureObject in [ MultiArchSubDirSetup x86_64 ] { thread.cpp time.cpp tls.cpp + + generic_atomic.cpp ; } } diff --git a/src/system/libroot/os/arch/x86_64/atomic.S b/src/system/libroot/os/arch/x86_64/atomic.S deleted file mode 100644 index b88af32..0000000 --- a/src/system/libroot/os/arch/x86_64/atomic.S +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2013, Paweł Dziepak, pdziepak@xxxxxxxxxxx. - * Copyright 2012, Alex Smith, alex@xxxxxxxxxxxxxxxx. - * Distributed under the terms of the MIT License. - */ - - -#include <asm_defs.h> - - -.text - - -/* int32 atomic_set(int32* value, int32 newValue) */ -FUNCTION(atomic_set): - sfence - movl %esi, (%rdi) - ret -FUNCTION_END(atomic_set) - - -/* int32 atomic_get_and_set(int32* value, int32 newValue) */ -FUNCTION(atomic_get_and_set): - movl %esi, %eax - xchgl %eax, (%rdi) - ret -FUNCTION_END(atomic_get_and_set) - - -/* int32 atomic_test_and_set(int32* value, int32 newValue, int32 testAgainst) */ -FUNCTION(atomic_test_and_set): - movl %edx, %eax - lock - cmpxchgl %esi, (%rdi) - ret -FUNCTION_END(atomic_test_and_set) - - -/* int32 atomic_add(int32* value, int32 addValue) */ -FUNCTION(atomic_add): - movl %esi, %eax - lock - xaddl %eax, (%rdi) - ret -FUNCTION_END(atomic_add) - - -/* int32 atomic_and(int32* value, int32 andValue) */ -FUNCTION(atomic_and): - movl (%rdi), %eax -1: movl %eax, %edx - movl %eax, %ecx - andl %esi, %edx - lock - cmpxchgl %edx, (%rdi) - jnz 1b - movl %ecx, %eax - ret -FUNCTION_END(atomic_and) - - -/* int32 atomic_or(int32* value, int32 orValue) */ -FUNCTION(atomic_or): - movl (%rdi), %eax -1: movl %eax, %edx - movl %eax, %ecx - orl %esi, %edx - lock - cmpxchgl %edx, (%rdi) - jnz 1b - movl %ecx, %eax - ret -FUNCTION_END(atomic_or) - - -/* int32 atomic_get(int32* value) */ -FUNCTION(atomic_get): - movl (%rdi), %eax - lfence - ret -FUNCTION_END(atomic_get) - - -/* int64 atomic_set64(int64* value, int64 newValue) */ -FUNCTION(atomic_set64): - sfence - movq %rsi, (%rdi) - ret -FUNCTION_END(atomic_set64) - - -/* int64 atomic_get_and_set64(int64* value, int64 newValue) */ -FUNCTION(atomic_get_and_set64): - movq %rsi, %rax - xchgq %rax, (%rdi) - ret -FUNCTION_END(atomic_get_and_set64) - - -/* int64 atomic_test_and_set64(int64* value, int64 newValue, - int64 testAgainst) */ -FUNCTION(atomic_test_and_set64): - movq %rdx, %rax - lock - cmpxchgq %rsi, (%rdi) - ret -FUNCTION_END(atomic_test_and_set64) - - -/* int64 atomic_add64(int64* value, int64 addValue) */ -FUNCTION(atomic_add64): - movq %rsi, %rax - lock - xaddq %rax, (%rdi) - ret -FUNCTION_END(atomic_add64) - - -/* int64 atomic_and64(int64* value, int64 andValue) */ -FUNCTION(atomic_and64): - movq (%rdi), %rax -1: movq %rax, %rdx - movq %rax, %rcx - andq %rsi, %rdx - lock - cmpxchgq %rdx, (%rdi) - jnz 1b - movq %rcx, %rax - ret -FUNCTION_END(atomic_and64) - - -/* int64 atomic_or64(int64* value, int64 orValue) */ -FUNCTION(atomic_or64): - movq (%rdi), %rax -1: movq %rax, %rdx - movq %rax, %rcx - orq %rsi, %rdx - lock - cmpxchgq %rdx, (%rdi) - jnz 1b - movq %rcx, %rax - ret -FUNCTION_END(atomic_or64) - - -/* int64 atomic_get64(int64* value) */ -FUNCTION(atomic_get64): - movq (%rdi), %rax - lfence - ret -FUNCTION_END(atomic_get64) - diff --git a/src/system/runtime_loader/arch/arm/Jamfile b/src/system/runtime_loader/arch/arm/Jamfile index afc33d3..86d9d2b 100644 --- a/src/system/runtime_loader/arch/arm/Jamfile +++ b/src/system/runtime_loader/arch/arm/Jamfile @@ -10,7 +10,6 @@ SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; StaticLibrary libruntime_loader_$(TARGET_ARCH).a : arch_relocate.cpp : - <src!system!libroot!os!arch!$(TARGET_ARCH)!$(architecture)>atomic.o <src!system!libroot!os!arch!$(TARGET_ARCH)!$(architecture)>thread.o <src!system!libroot!posix!string!arch!$(TARGET_ARCH)!$(architecture)>arch_string.o diff --git a/src/system/runtime_loader/arch/x86_64/Jamfile b/src/system/runtime_loader/arch/x86_64/Jamfile index b9baa79..42e72d4 100644 --- a/src/system/runtime_loader/arch/x86_64/Jamfile +++ b/src/system/runtime_loader/arch/x86_64/Jamfile @@ -10,7 +10,6 @@ SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; StaticLibrary libruntime_loader_$(TARGET_ARCH).a : arch_relocate.cpp : - <src!system!libroot!os!arch!$(TARGET_ARCH)!$(architecture)>atomic.o <src!system!libroot!os!arch!$(TARGET_ARCH)!$(architecture)>thread.o <src!system!libroot!posix!string!arch!$(TARGET_ARCH)!$(architecture)>arch_string.o ; ############################################################################ Commit: a4cdc6072cafccc8bd7d3c4a4458bf72ff68272c URL: http://cgit.haiku-os.org/haiku/commit/?id=a4cdc60 Author: Paweł Dziepak <pdziepak@xxxxxxxxxxx> Date: Mon Aug 25 13:44:12 2014 UTC build: remove B_USE_BUILTIN_ATOMIC_FUNCTIONS No reason not to use GCC atomic support on non-x86 archs. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/headers/os/support/SupportDefs.h b/headers/os/support/SupportDefs.h index b863334..7e47018 100644 --- a/headers/os/support/SupportDefs.h +++ b/headers/os/support/SupportDefs.h @@ -215,8 +215,7 @@ extern void* get_stack_frame(void); /* Use the built-in atomic functions, if requested and available. */ -#if defined(B_USE_BUILTIN_ATOMIC_FUNCTIONS) && __GNUC__ > 4 \ - || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) static inline void @@ -321,8 +320,7 @@ atomic_get64(int64* value) } -#else // B_USE_BUILTIN_ATOMIC_FUNCTIONS && __GNUC__ > 4 - // || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) +#else // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) #ifdef __cplusplus extern "C" { ############################################################################ Revision: hrev47741 Commit: 721a07ac24df63af87afd8d52f5e08ec6566c9e0 URL: http://cgit.haiku-os.org/haiku/commit/?id=721a07a Author: Paweł Dziepak <pdziepak@xxxxxxxxxxx> Date: Mon Aug 25 13:45:26 2014 UTC libroot: remove ATOMIC_FUNCS_ARE_SYSCALLS GCC knows whether these functions need to be implemented using syscalls (or more clever solutions like in Linux) and calls libgcc in such case. Signed-off-by: Paweł Dziepak <pdziepak@xxxxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/src/system/libroot/os/arch/generic/generic_atomic.cpp b/src/system/libroot/os/arch/generic/generic_atomic.cpp index dce3a5b..cc21f1d 100644 --- a/src/system/libroot/os/arch/generic/generic_atomic.cpp +++ b/src/system/libroot/os/arch/generic/generic_atomic.cpp @@ -7,8 +7,6 @@ #include <atomic> #include <sys/types.h> -#ifndef ATOMIC_FUNCS_ARE_SYSCALLS - extern "C" [[gnu::optimize("omit-frame-pointer")]] void atomic_set(int32_t* ptr, int32_t value) @@ -123,5 +121,3 @@ atomic_get64(int64_t* ptr) return obj.load(std::memory_order_acquire); } - -#endif /* ATOMIC64_FUNCS_ARE_SYSCALLS */