From 4d91a1b3c318a28050d45895d722ce5f34e3d0b9 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 17 Aug 2019 12:59:37 -0400 Subject: [PATCH] BooObject: Make atomic ordering constraints less strict Increasing a reference count is able to always be relaxed. New references to an object can only be formed from an existing reference. The passing of an existing reference from one thread to another will already necessitate the use of synchronization primitives, so this is a safe change to make. Regardless, nothing other than the object itself directly relies on the reference count, so this will always be a suitably atomic operation, even in the face of no synchronization primitives. In the case of decrementing the reference count, it's sufficient to treat it with release semantics and follow it up with an atomic thread fence. This ensures that all accesses to the object in one thread will occur before the delete occurs in another thread (if the situation ever occurs). This should make for a slightly more efficient increment and decrement. --- include/boo/BooObject.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boo/BooObject.hpp b/include/boo/BooObject.hpp index c1134e4..52d942e 100644 --- a/include/boo/BooObject.hpp +++ b/include/boo/BooObject.hpp @@ -14,9 +14,10 @@ protected: public: virtual std::unique_lock destructorLock() = 0; - void increment() { m_refCount++; } + void increment() { m_refCount.fetch_add(1, std::memory_order_relaxed); } void decrement() { - if (m_refCount.fetch_sub(1) == 1) { + if (m_refCount.fetch_sub(1, std::memory_order_acq_rel) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); auto lk = destructorLock(); delete this; }