Use C++11 atomics for our intrusive pointers

This commit is contained in:
Alexander A. Klimov 2019-03-11 12:05:01 +01:00 committed by Michael Friedrich
parent 58ae29acac
commit cfd0d86b9b
2 changed files with 17 additions and 17 deletions

View File

@ -21,6 +21,14 @@ static std::map<String, int> l_ObjectCounts;
static Timer::Ptr l_ObjectCountTimer; static Timer::Ptr l_ObjectCountTimer;
#endif /* I2_LEAK_DEBUG */ #endif /* I2_LEAK_DEBUG */
/**
* Constructor for the Object class.
*/
Object::Object()
{
m_References.store(0);
}
/** /**
* Destructor for the Object class. * Destructor for the Object class.
*/ */
@ -238,28 +246,18 @@ INITIALIZE_ONCE([]() {
void icinga::intrusive_ptr_add_ref(Object *object) void icinga::intrusive_ptr_add_ref(Object *object)
{ {
#ifdef I2_LEAK_DEBUG #ifdef I2_LEAK_DEBUG
if (object->m_References == 0) if (object->m_References.fetch_add(1) == 0u)
TypeAddObject(object); TypeAddObject(object);
#else /* I2_LEAK_DEBUG */
object->m_References.fetch_add(1);
#endif /* I2_LEAK_DEBUG */ #endif /* I2_LEAK_DEBUG */
#ifdef _WIN32
InterlockedIncrement(&object->m_References);
#else /* _WIN32 */
__sync_add_and_fetch(&object->m_References, 1);
#endif /* _WIN32 */
} }
void icinga::intrusive_ptr_release(Object *object) void icinga::intrusive_ptr_release(Object *object)
{ {
uintptr_t refs; auto previous (object->m_References.fetch_sub(1));
#ifdef _WIN32 if (previous == 1u) {
refs = InterlockedDecrement(&object->m_References);
#else /* _WIN32 */
refs = __sync_sub_and_fetch(&object->m_References, 1);
#endif /* _WIN32 */
if (unlikely(refs == 0)) {
#ifdef I2_LEAK_DEBUG #ifdef I2_LEAK_DEBUG
TypeRemoveObject(object); TypeRemoveObject(object);
#endif /* I2_LEAK_DEBUG */ #endif /* I2_LEAK_DEBUG */

View File

@ -6,7 +6,9 @@
#include "base/i2-base.hpp" #include "base/i2-base.hpp"
#include "base/debug.hpp" #include "base/debug.hpp"
#include <boost/smart_ptr/intrusive_ptr.hpp> #include <boost/smart_ptr/intrusive_ptr.hpp>
#include <atomic>
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <vector> #include <vector>
using boost::intrusive_ptr; using boost::intrusive_ptr;
@ -154,7 +156,7 @@ class Object
public: public:
DECLARE_PTR_TYPEDEFS(Object); DECLARE_PTR_TYPEDEFS(Object);
Object() = default; Object();
virtual ~Object(); virtual ~Object();
virtual String ToString() const; virtual String ToString() const;
@ -187,7 +189,7 @@ private:
Object(const Object& other) = delete; Object(const Object& other) = delete;
Object& operator=(const Object& rhs) = delete; Object& operator=(const Object& rhs) = delete;
uintptr_t m_References{0}; std::atomic<uint_fast64_t> m_References;
mutable uintptr_t m_Mutex{0}; mutable uintptr_t m_Mutex{0};
#ifdef I2_DEBUG #ifdef I2_DEBUG