From 8e88818447406c8f5c4f6133dfe4ac063c858e15 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Sun, 19 Apr 2020 21:08:17 +0000 Subject: Use std::conditional to selct correct type depending on if std::atomic is lock free. --- vespamalloc/src/vespamalloc/malloc/allocchunk.h | 28 +++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/vespamalloc/src/vespamalloc/malloc/allocchunk.h b/vespamalloc/src/vespamalloc/malloc/allocchunk.h index f55f6c33cee..7a552c4ab5e 100644 --- a/vespamalloc/src/vespamalloc/malloc/allocchunk.h +++ b/vespamalloc/src/vespamalloc/malloc/allocchunk.h @@ -20,21 +20,28 @@ struct TaggedPtr { TaggedPtr() noexcept : _ptr(nullptr), _tag(0) { } TaggedPtr(void *h, size_t t) noexcept : _ptr(h), _tag(t) {} + void *_ptr; + size_t _tag; +}; + #if defined(__x86_64__) - #define VESPA_USE_ATOMIC_TAGGEDPTR - TaggedPtr load(std::memory_order = std::memory_order_seq_cst) { +struct AtomicTaggedPtr { + AtomicTaggedPtr() noexcept : _ptr(nullptr), _tag(0) { } + AtomicTaggedPtr(void *h, size_t t) noexcept : _ptr(h), _tag(t) {} + + AtomicTaggedPtr load(std::memory_order = std::memory_order_seq_cst) { // Note that this is NOT an atomic load. The current use as the initial load // in a compare_exchange loop is safe as a teared load will just give a retry. return *this; } - void store(TaggedPtr ptr) { + void store(AtomicTaggedPtr ptr) { // Note that this is NOT an atomic store. The current use is in a unit test as an initial // store before any threads are started. Just done so to keep api compatible with std::atomic as // that is the preferred implementation.. *this = ptr; } bool - compare_exchange_weak(TaggedPtr & oldPtr, TaggedPtr newPtr, std::memory_order, std::memory_order) { + compare_exchange_weak(AtomicTaggedPtr & oldPtr, AtomicTaggedPtr newPtr, std::memory_order, std::memory_order) { char result; __asm__ volatile ( "lock ;" @@ -50,21 +57,20 @@ struct TaggedPtr { ); return result; } -#endif void *_ptr; size_t _tag; } __attribute__ ((aligned (16))); +#else + using AtomicTaggedPtr = TagTaggedPtr; +#endif + class AFListBase { public: - using HeadPtr = TaggedPtr; -#ifdef VESPA_USE_ATOMIC_TAGGEDPTR - using AtomicHeadPtr = HeadPtr; -#else - using AtomicHeadPtr = std::atomic; -#endif + using HeadPtr = std::conditional::is_always_lock_free, TaggedPtr, AtomicTaggedPtr>::type; + using AtomicHeadPtr = std::conditional::is_always_lock_free, std::atomic, AtomicTaggedPtr>::type; AFListBase() : _next(nullptr) { } void setNext(AFListBase * csl) { _next = csl; } -- cgit v1.2.3