]> granicus.if.org Git - icinga2/commitdiff
Decrease memory usage for the Object class
authorGunnar Beutner <gunnar@beutner.name>
Tue, 19 Jan 2016 14:25:44 +0000 (15:25 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Tue, 23 Feb 2016 09:46:13 +0000 (10:46 +0100)
refs #10963

lib/base/object.cpp
lib/base/objectlock.hpp

index 1a6d1c9ab647b3fa6bfcaaca2180a22e94b3b0da..2d2779a3875593cc1bfd1e77a02984ce09ddb5cf 100644 (file)
@@ -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<boost::recursive_mutex *>(m_Mutex);
+}
 
 /**
  * Returns a string representation for the object.
index 87d108fea126dea6a31596a10cd45b293dbd7608..2ef73ecf61e0dfd25995e599825076a6d2f9a904 100644 (file)
@@ -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<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)
        {
                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<boost::recursive_mutex *>(m_Object->m_Mutex)->unlock();
                        m_Locked = false;
                }
        }