From badeea7604a01352f0ca0a95f6bbb9f1ce4f227e Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 19 Jan 2016 15:25:44 +0100 Subject: [PATCH] Decrease memory usage for the Object class refs #10963 --- lib/base/object.cpp | 6 ++-- lib/base/objectlock.hpp | 64 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lib/base/object.cpp b/lib/base/object.cpp index 1a6d1c9ab..2d2779a38 100644 --- a/lib/base/object.cpp +++ b/lib/base/object.cpp @@ -40,7 +40,7 @@ static Timer::Ptr l_ObjectCountTimer; * Default constructor for the Object class. */ Object::Object(void) - : m_References(0) + : m_References(0), m_Mutex(0) #ifdef I2_DEBUG , m_LockOwner(0) #endif /* I2_DEBUG */ @@ -50,7 +50,9 @@ Object::Object(void) * Destructor for the Object class. */ Object::~Object(void) -{ } +{ + delete reinterpret_cast(m_Mutex); +} /** * Returns a string representation for the object. diff --git a/lib/base/objectlock.hpp b/lib/base/objectlock.hpp index 87d108fea..2ef73ecf6 100644 --- a/lib/base/objectlock.hpp +++ b/lib/base/objectlock.hpp @@ -22,6 +22,9 @@ #include "base/object.hpp" +#define I2MUTEX_UNLOCKED 0 +#define I2MUTEX_LOCKED 1 + namespace icinga { @@ -53,11 +56,49 @@ public: Lock(); } + inline static void LockMutex(const Object *object) + { + unsigned int it = 0; + +#ifdef _WIN32 +# ifdef _WIN64 + while (InterlockedCompareExchange64(&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED) { +# else /* _WIN64 */ + while (InterlockedCompareExchange(&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED) { +# endif /* _WIN64 */ +#else /* _WIN32 */ + while (!__sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_UNLOCKED, I2MUTEX_LOCKED)) { +#endif /* _WIN32 */ + if (object->m_Mutex > I2MUTEX_LOCKED) { + boost::recursive_mutex *mtx = reinterpret_cast(object->m_Mutex); + mtx->lock(); + + return; + } + + Spin(it); + it++; + } + + boost::recursive_mutex *mtx = new boost::recursive_mutex(); + mtx->lock(); +#ifdef _WIN32 +# ifdef _WIN64 + InterlockedCompareExchange64(&object->m_Mutex, reinterpret_cast(mtx), I2MUTEX_LOCKED); +# else /* _WIN64 */ + InterlockedCompareExchange(&object->m_Mutex, reinterpret_cast(mtx), I2MUTEX_LOCKED); +# endif /* _WIN64 */ +#else /* _WIN32 */ + __sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_LOCKED, reinterpret_cast(mtx)); +#endif /* _WIN32 */ + } + inline void Lock(void) { ASSERT(!m_Locked && m_Object != NULL); - m_Object->m_Mutex.lock(); + LockMutex(m_Object); + m_Locked = true; #ifdef I2_DEBUG @@ -69,6 +110,25 @@ public: #endif /* I2_DEBUG */ } + inline static void Spin(unsigned int it) + { + if (it < 8) { + /* Do nothing. */ + } +#ifdef SPIN_PAUSE + else if (it < 16) { + SPIN_PAUSE(); + } +#endif /* SPIN_PAUSE */ + else { +#ifdef _WIN32 + Sleep(0); +#else /* _WIN32 */ + sched_yield(); +#endif /* _WIN32 */ + } + } + inline void Unlock(void) { #ifdef I2_DEBUG @@ -82,7 +142,7 @@ public: #endif /* I2_DEBUG */ if (m_Locked) { - m_Object->m_Mutex.unlock(); + reinterpret_cast(m_Object->m_Mutex)->unlock(); m_Locked = false; } } -- 2.40.0