mirror of https://github.com/Icinga/icinga2.git
parent
684ad2641a
commit
187d443447
|
@ -205,7 +205,8 @@ CMAKE_OPTS="$CMAKE_OPTS -DBOOST_LIBRARYDIR=/usr/lib/boost141 \
|
||||||
%if "%{_vendor}" != "suse"
|
%if "%{_vendor}" != "suse"
|
||||||
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{_libdir}/nagios/plugins"
|
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{_libdir}/nagios/plugins"
|
||||||
%else
|
%else
|
||||||
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{_prefix}/lib/nagios/plugins"
|
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{_prefix}/lib/nagios/plugins \
|
||||||
|
-DCMAKE_C_FLAGS='-march=i686' -DCMAKE_CXX_FLAGS='-march=i686'"
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%if 0%{?use_systemd}
|
%if 0%{?use_systemd}
|
||||||
|
|
|
@ -30,7 +30,7 @@ set(base_SOURCES
|
||||||
ringbuffer.cpp scriptfunction.cpp scriptfunctionwrapper.cpp
|
ringbuffer.cpp scriptfunction.cpp scriptfunctionwrapper.cpp
|
||||||
scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
|
scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
|
||||||
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp
|
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp
|
||||||
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp threadpool.cpp timer.cpp
|
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp
|
||||||
tlsstream.cpp tlsutility.cpp type.cpp unixsocket.cpp utility.cpp value.cpp
|
tlsstream.cpp tlsutility.cpp type.cpp unixsocket.cpp utility.cpp value.cpp
|
||||||
value-operators.cpp workqueue.cpp
|
value-operators.cpp workqueue.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "base/i2-base.hpp"
|
#include "base/i2-base.hpp"
|
||||||
#include "base/debug.hpp"
|
#include "base/debug.hpp"
|
||||||
|
#include "base/thinmutex.hpp"
|
||||||
#include <boost/thread/thread.hpp>
|
#include <boost/thread/thread.hpp>
|
||||||
|
|
||||||
#ifndef _DEBUG
|
#ifndef _DEBUG
|
||||||
|
@ -179,18 +180,14 @@ private:
|
||||||
Object(const Object& other);
|
Object(const Object& other);
|
||||||
Object& operator=(const Object& rhs);
|
Object& operator=(const Object& rhs);
|
||||||
|
|
||||||
#ifndef _DEBUG
|
mutable ThinMutex m_Mutex;
|
||||||
typedef boost::mutex MutexType;
|
|
||||||
#else /* _DEBUG */
|
|
||||||
typedef boost::recursive_mutex MutexType;
|
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
static boost::mutex m_DebugMutex;
|
static boost::mutex m_DebugMutex;
|
||||||
mutable bool m_Locked;
|
mutable bool m_Locked;
|
||||||
mutable boost::thread::id m_LockOwner;
|
mutable boost::thread::id m_LockOwner;
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
mutable MutexType m_Mutex;
|
|
||||||
|
|
||||||
friend struct ObjectLock;
|
friend struct ObjectLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
ObjectLock::ObjectLock(void)
|
ObjectLock::ObjectLock(void)
|
||||||
: m_Object(NULL), m_Lock()
|
: m_Object(NULL), m_Locked(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
ObjectLock::~ObjectLock(void)
|
ObjectLock::~ObjectLock(void)
|
||||||
|
@ -32,14 +32,14 @@ ObjectLock::~ObjectLock(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectLock::ObjectLock(const Object::Ptr& object)
|
ObjectLock::ObjectLock(const Object::Ptr& object)
|
||||||
: m_Object(object.get()), m_Lock()
|
: m_Object(object.get()), m_Locked(false)
|
||||||
{
|
{
|
||||||
if (m_Object)
|
if (m_Object)
|
||||||
Lock();
|
Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectLock::ObjectLock(const Object *object)
|
ObjectLock::ObjectLock(const Object *object)
|
||||||
: m_Object(object), m_Lock()
|
: m_Object(object), m_Locked(false)
|
||||||
{
|
{
|
||||||
if (m_Object)
|
if (m_Object)
|
||||||
Lock();
|
Lock();
|
||||||
|
@ -47,10 +47,11 @@ ObjectLock::ObjectLock(const Object *object)
|
||||||
|
|
||||||
void ObjectLock::Lock(void)
|
void ObjectLock::Lock(void)
|
||||||
{
|
{
|
||||||
ASSERT(!m_Lock.owns_lock() && m_Object != NULL);
|
ASSERT(!m_Locked && m_Object != NULL);
|
||||||
ASSERT(!m_Object->OwnsLock());
|
ASSERT(!m_Object->OwnsLock());
|
||||||
|
|
||||||
m_Lock = Object::MutexType::scoped_lock(m_Object->m_Mutex);
|
m_Object->m_Mutex.Lock();
|
||||||
|
m_Locked = true;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
{
|
{
|
||||||
|
@ -66,11 +67,13 @@ void ObjectLock::Unlock(void)
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(Object::m_DebugMutex);
|
boost::mutex::scoped_lock lock(Object::m_DebugMutex);
|
||||||
|
if (m_Locked)
|
||||||
if (m_Lock.owns_lock())
|
|
||||||
m_Object->m_Locked = false;
|
m_Object->m_Locked = false;
|
||||||
}
|
}
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
m_Lock = Object::MutexType::scoped_lock();
|
if (m_Locked) {
|
||||||
|
m_Object->m_Mutex.Unlock();
|
||||||
|
m_Locked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Object *m_Object;
|
const Object *m_Object;
|
||||||
Object::MutexType::scoped_lock m_Lock;
|
bool m_Locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software Foundation *
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "base/thinmutex.hpp"
|
||||||
|
#include "base/initialize.hpp"
|
||||||
|
#include "base/timer.hpp"
|
||||||
|
#include "base/convert.hpp"
|
||||||
|
#include "base/logger.hpp"
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
using namespace icinga;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
uintptr_t ThinMutex::m_TotalMutexes;
|
||||||
|
uintptr_t ThinMutex::m_InflatedMutexes;
|
||||||
|
uintptr_t ThinMutex::m_DeadMutexes;
|
||||||
|
|
||||||
|
static Timer::Ptr l_Timer;
|
||||||
|
|
||||||
|
void ThinMutex::DebugTimerHandler(void)
|
||||||
|
{
|
||||||
|
Log(LogNotice, "ThinMutex")
|
||||||
|
<< "Mutexes: " << ThinMutex::m_TotalMutexes - ThinMutex::m_DeadMutexes
|
||||||
|
<< ", Inflated Mutexes: " << ThinMutex::m_InflatedMutexes
|
||||||
|
<< ", Dead Mutexes: " << ThinMutex::m_DeadMutexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitThinMutex(void)
|
||||||
|
{
|
||||||
|
l_Timer = make_shared<Timer>();
|
||||||
|
l_Timer->SetInterval(10);
|
||||||
|
l_Timer->OnTimerExpired.connect(boost::bind(&ThinMutex::DebugTimerHandler));
|
||||||
|
l_Timer->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
INITIALIZE_ONCE(&InitThinMutex);
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
|
void ThinMutex::MakeNative(void)
|
||||||
|
{
|
||||||
|
boost::mutex *mtx = new boost::mutex();
|
||||||
|
mtx->lock();
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifdef _WIN64
|
||||||
|
InterlockedCompareExchange64(&m_Data, reinterpret_cast<LONGLONG>(mtx), THINLOCK_LOCKED);
|
||||||
|
# else /* _WIN64 */
|
||||||
|
InterlockedCompareExchange(&m_Data, reinterpret_cast<LONG>(mtx), THINLOCK_LOCKED);
|
||||||
|
# endif /* _WIN64 */
|
||||||
|
#else /* _WIN32 */
|
||||||
|
__sync_bool_compare_and_swap(&m_Data, THINLOCK_LOCKED, reinterpret_cast<uintptr_t>(mtx));
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# ifdef _WIN32
|
||||||
|
InterlockedIncrement(&m_InflatedMutexes);
|
||||||
|
# else /* _WIN32 */
|
||||||
|
__sync_fetch_and_add(&m_InflatedMutexes, 1);
|
||||||
|
# endif /* _WIN32 */
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThinMutex::DestroyNative(void)
|
||||||
|
{
|
||||||
|
delete reinterpret_cast<boost::mutex *>(m_Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThinMutex::LockNative(void)
|
||||||
|
{
|
||||||
|
boost::mutex *mtx = reinterpret_cast<boost::mutex *>(m_Data);
|
||||||
|
mtx->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThinMutex::UnlockNative(void)
|
||||||
|
{
|
||||||
|
boost::mutex *mtx = reinterpret_cast<boost::mutex *>(m_Data);
|
||||||
|
mtx->unlock();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software Foundation *
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef THINMUTEX_H
|
||||||
|
#define THINMUTEX_H
|
||||||
|
|
||||||
|
#include "base/i2-base.hpp"
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sched.h>
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1310 && (defined(_M_IX86) || defined(_M_X64))
|
||||||
|
extern "C" void _mm_pause();
|
||||||
|
#pragma intrinsic(_mm_pause)
|
||||||
|
#define SPIN_PAUSE() _mm_pause()
|
||||||
|
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
|
#define SPIN_PAUSE() __asm__ __volatile__("rep; nop" : : : "memory")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define THINLOCK_UNLOCKED 0
|
||||||
|
#define THINLOCK_LOCKED 1
|
||||||
|
|
||||||
|
namespace icinga {
|
||||||
|
|
||||||
|
class I2_BASE_API ThinMutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline ThinMutex(void)
|
||||||
|
: m_Data(THINLOCK_UNLOCKED)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# ifdef _WIN32
|
||||||
|
InterlockedIncrement(&m_TotalMutexes);
|
||||||
|
# else /* _WIN32 */
|
||||||
|
__sync_fetch_and_add(&m_TotalMutexes, 1);
|
||||||
|
# endif /* _WIN32 */
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ~ThinMutex(void)
|
||||||
|
{
|
||||||
|
if (m_Data > THINLOCK_LOCKED)
|
||||||
|
DestroyNative();
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# ifdef _WIN32
|
||||||
|
InterlockedDecrement(&m_TotalMutexes);
|
||||||
|
# else /* _WIN32 */
|
||||||
|
__sync_fetch_and_add(&m_DeadMutexes, 1);
|
||||||
|
# endif /* _WIN32 */
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
inline 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 Lock(void)
|
||||||
|
{
|
||||||
|
bool contended = false;
|
||||||
|
unsigned int it = 0;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifdef _WIN64
|
||||||
|
while (InterlockedCompareExchange64(&m_Data, THINLOCK_LOCKED, THINLOCK_UNLOCKED) != THINLOCK_UNLOCKED) {
|
||||||
|
# else /* _WIN64 */
|
||||||
|
while (InterlockedCompareExchange(&m_Data, THINLOCK_LOCKED, THINLOCK_UNLOCKED) != THINLOCK_UNLOCKED) {
|
||||||
|
# endif /* _WIN64 */
|
||||||
|
#else /* _WIN32 */
|
||||||
|
while (!__sync_bool_compare_and_swap(&m_Data, THINLOCK_UNLOCKED, THINLOCK_LOCKED)) {
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
if (m_Data > THINLOCK_LOCKED) {
|
||||||
|
LockNative();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
contended = true;
|
||||||
|
|
||||||
|
Spin(it);
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contended)
|
||||||
|
MakeNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeNative(void);
|
||||||
|
void DestroyNative(void);
|
||||||
|
|
||||||
|
void LockNative(void);
|
||||||
|
void UnlockNative(void);
|
||||||
|
|
||||||
|
inline void Unlock(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifdef _WIN64
|
||||||
|
if (InterlockedCompareExchange64(&m_Data, THINLOCK_UNLOCKED, THINLOCK_LOCKED) != THINLOCK_LOCKED)
|
||||||
|
# else /* _WIN64 */
|
||||||
|
if (InterlockedCompareExchange(&m_Data, THINLOCK_UNLOCKED, THINLOCK_LOCKED) != THINLOCK_LOCKED)
|
||||||
|
# endif /* _WIN64 */
|
||||||
|
#else /* _WIN32 */
|
||||||
|
if (!__sync_bool_compare_and_swap(&m_Data, THINLOCK_LOCKED, THINLOCK_UNLOCKED))
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
UnlockNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
static void DebugTimerHandler(void);
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifdef _WIN64
|
||||||
|
LONGLONG m_Data;
|
||||||
|
# else /* _WIN64 */
|
||||||
|
LONG m_Data;
|
||||||
|
# endif /* _WIN64 */
|
||||||
|
#else /* _WIN32 */
|
||||||
|
uintptr_t m_Data;
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
static uintptr_t m_TotalMutexes;
|
||||||
|
static uintptr_t m_InflatedMutexes;
|
||||||
|
static uintptr_t m_DeadMutexes;
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* THINMUTEX_H */
|
Loading…
Reference in New Issue