From aa58f7e431a5b295d9d83c59418d97bec7180fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Mon, 25 Aug 2014 15:01:44 +0200 Subject: [PATCH] os/arch: implement all atomic_*() using std::atomic<> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../os/arch/generic/generic_atomic.cpp | 116 +++++++++++++++++- 1 file changed, 112 insertions(+), 4 deletions(-) diff --git a/src/system/libroot/os/arch/generic/generic_atomic.cpp b/src/system/libroot/os/arch/generic/generic_atomic.cpp index 73b5c56697..dce3a5b9e1 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 -atomic_get_and_set(int32_t* ptr, int32_t value) + +extern "C" [[gnu::optimize("omit-frame-pointer")]] void +atomic_set(int32_t* ptr, int32_t value) { - auto& obj = *reinterpret_cast*>(ptr); - return obj.exchange(value); + auto& obj = *reinterpret_cast*>(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*>(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*>(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*>(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*>(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*>(ptr); + return obj.fetch_or(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int32_t +atomic_get(int32_t* ptr) +{ + auto& obj = *reinterpret_cast*>(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*>(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*>(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*>(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*>(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*>(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*>(ptr); + return obj.fetch_or(value); +} + + +extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t +atomic_get64(int64_t* ptr) +{ + auto& obj = *reinterpret_cast*>(ptr); + return obj.load(std::memory_order_acquire); +} + + #endif /* ATOMIC64_FUNCS_ARE_SYSCALLS */