[haiku-commits] haiku: hrev47741 - src/system/libroot/os/arch/arm src/system/libroot/os/arch/generic src/system/libroot/os/arch/x86_64 headers/os/support headers/private/kernel/arch/x86/64

  • From: pdziepak@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 25 Aug 2014 23:37:39 +0200 (CEST)

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 */


Other related posts:

  • » [haiku-commits] haiku: hrev47741 - src/system/libroot/os/arch/arm src/system/libroot/os/arch/generic src/system/libroot/os/arch/x86_64 headers/os/support headers/private/kernel/arch/x86/64 - pdziepak