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@quarnos.org>
This commit is contained in:
parent
2e2c9bd3d0
commit
aa58f7e431
@ -9,11 +9,119 @@
|
|||||||
|
|
||||||
#ifndef ATOMIC_FUNCS_ARE_SYSCALLS
|
#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)
|
atomic_get_and_set(int32_t* ptr, int32_t value)
|
||||||
{
|
{
|
||||||
auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr);
|
auto& obj = *reinterpret_cast<std::atomic<int32_t>*>(ptr);
|
||||||
return obj.exchange(value);
|
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 */
|
#endif /* ATOMIC64_FUNCS_ARE_SYSCALLS */
|
||||||
|
Loading…
Reference in New Issue
Block a user