Decrease memory usage for the Object class

refs #10963
This commit is contained in:
Gunnar Beutner 2016-01-19 15:25:44 +01:00
parent d50c8e1085
commit b1aa6cc98a
3 changed files with 71 additions and 7 deletions

View File

@ -40,7 +40,7 @@ static Timer::Ptr l_ObjectCountTimer;
* Default constructor for the Object class. * Default constructor for the Object class.
*/ */
Object::Object(void) Object::Object(void)
: m_References(0) : m_References(0), m_Mutex(0)
#ifdef I2_DEBUG #ifdef I2_DEBUG
, m_LockOwner(0) , m_LockOwner(0)
#endif /* I2_DEBUG */ #endif /* I2_DEBUG */
@ -50,7 +50,9 @@ Object::Object(void)
* Destructor for the Object class. * Destructor for the Object class.
*/ */
Object::~Object(void) Object::~Object(void)
{ } {
delete reinterpret_cast<boost::recursive_mutex *>(m_Mutex);
}
/** /**
* Returns a string representation for the object. * Returns a string representation for the object.

View File

@ -117,8 +117,8 @@ private:
Object(const Object& other); Object(const Object& other);
Object& operator=(const Object& rhs); Object& operator=(const Object& rhs);
uintptr_t m_References; intptr_t m_References;
mutable boost::recursive_mutex m_Mutex; mutable uintptr_t m_Mutex;
#ifdef I2_DEBUG #ifdef I2_DEBUG
# ifndef _WIN32 # ifndef _WIN32
@ -153,13 +153,15 @@ inline void intrusive_ptr_add_ref(Object *object)
inline void intrusive_ptr_release(Object *object) inline void intrusive_ptr_release(Object *object)
{ {
uintptr_t refs; intptr_t refs;
#ifdef _WIN32 #ifdef _WIN32
refs = InterlockedDecrement(&object->m_References); refs = InterlockedDecrement(&object->m_References);
#else /* _WIN32 */ #else /* _WIN32 */
refs = __sync_sub_and_fetch(&object->m_References, 1); refs = __sync_sub_and_fetch(&object->m_References, 1);
#endif /* _WIN32 */ #endif /* _WIN32 */
ASSERT(refs >= 0);
if (refs == 0) { if (refs == 0) {
#ifdef I2_DEBUG #ifdef I2_DEBUG
TypeRemoveObject(object); TypeRemoveObject(object);

View File

@ -22,6 +22,9 @@
#include "base/object.hpp" #include "base/object.hpp"
#define I2MUTEX_UNLOCKED 0
#define I2MUTEX_LOCKED 1
namespace icinga namespace icinga
{ {
@ -53,11 +56,49 @@ public:
Lock(); 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<boost::recursive_mutex *>(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<LONGLONG>(mtx), I2MUTEX_LOCKED);
# else /* _WIN64 */
InterlockedCompareExchange(&object->m_Mutex, reinterpret_cast<LONG>(mtx), I2MUTEX_LOCKED);
# endif /* _WIN64 */
#else /* _WIN32 */
__sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_LOCKED, reinterpret_cast<uintptr_t>(mtx));
#endif /* _WIN32 */
}
inline void Lock(void) inline void Lock(void)
{ {
ASSERT(!m_Locked && m_Object != NULL); ASSERT(!m_Locked && m_Object != NULL);
m_Object->m_Mutex.lock(); LockMutex(m_Object);
m_Locked = true; m_Locked = true;
#ifdef I2_DEBUG #ifdef I2_DEBUG
@ -69,6 +110,25 @@ public:
#endif /* I2_DEBUG */ #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) inline void Unlock(void)
{ {
#ifdef I2_DEBUG #ifdef I2_DEBUG
@ -82,7 +142,7 @@ public:
#endif /* I2_DEBUG */ #endif /* I2_DEBUG */
if (m_Locked) { if (m_Locked) {
m_Object->m_Mutex.unlock(); reinterpret_cast<boost::recursive_mutex *>(m_Object->m_Mutex)->unlock();
m_Locked = false; m_Locked = false;
} }
} }