Skip to content

Commit

Permalink
Locked<T>: optimistically use SpinMutex for intrusive_ptr to consume …
Browse files Browse the repository at this point in the history
…less RAM

std::mutex is 5 pointers large on x64, whereas std::atomic_flag at most one.
  • Loading branch information
Al2Klimov committed Sep 24, 2024
1 parent c61a741 commit be761c1
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions lib/base/atomic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#define ATOMIC_H

#include <atomic>
#include <boost/smart_ptr/intrusive_ptr.hpp>
#include <mutex>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -66,6 +67,24 @@ class SpinMutex
std::atomic_flag m_State = ATOMIC_FLAG_INIT;
};

template<typename T>
struct LockedMutex
{
using Mutex = std::mutex;
};

/**
* SpinMutex is 5 times smaller than std::mutex on x86_64.
* Also, it's fine for boost::intrusive_ptr which basically only performs atomic refcounting.
*
* @ingroup base
*/
template<typename T>
struct LockedMutex<boost::intrusive_ptr<T>>
{
using Mutex = SpinMutex;
};

/**
* Wraps any T into a std::atomic<T>-like interface that locks using a mutex.
*
Expand All @@ -80,20 +99,20 @@ class Locked
public:
inline T load() const
{
std::unique_lock<std::mutex> lock(m_Mutex);
std::unique_lock lock (m_Mutex);

return m_Value;
}

inline void store(T desired)
{
std::unique_lock<std::mutex> lock(m_Mutex);
std::unique_lock lock (m_Mutex);

m_Value = std::move(desired);
}

private:
mutable std::mutex m_Mutex;
mutable typename LockedMutex<T>::Mutex m_Mutex;
T m_Value;
};

Expand Down

0 comments on commit be761c1

Please sign in to comment.