2011-09-27 17:48:46 +00:00
|
|
|
// This code is in the public domain -- castano@gmail.com
|
|
|
|
|
|
|
|
#include "Mutex.h"
|
|
|
|
|
|
|
|
#if NV_OS_WIN32
|
|
|
|
|
|
|
|
#include "Win32.h"
|
|
|
|
|
2013-06-07 17:53:55 +00:00
|
|
|
#elif NV_OS_USE_PTHREAD
|
2011-09-27 17:48:46 +00:00
|
|
|
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <errno.h> // EBUSY
|
|
|
|
|
|
|
|
#endif // NV_OS
|
|
|
|
|
2018-02-06 02:55:07 +00:00
|
|
|
#if NV_USE_TELEMETRY3
|
|
|
|
#include <rad_tm.h>
|
|
|
|
#elif NV_USE_TELEMETRY
|
2015-03-24 19:14:49 +00:00
|
|
|
#include <telemetry.h>
|
|
|
|
extern HTELEMETRY tmContext;
|
|
|
|
#endif
|
|
|
|
|
2011-09-27 17:48:46 +00:00
|
|
|
using namespace nv;
|
|
|
|
|
|
|
|
|
|
|
|
#if NV_OS_WIN32
|
|
|
|
|
|
|
|
struct Mutex::Private {
|
2011-09-27 18:12:32 +00:00
|
|
|
CRITICAL_SECTION mutex;
|
2015-03-24 19:14:49 +00:00
|
|
|
const char * name;
|
2011-09-27 17:48:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-03-24 19:14:49 +00:00
|
|
|
Mutex::Mutex (const char * name) : m(new Private)
|
2011-09-27 17:48:46 +00:00
|
|
|
{
|
2011-09-27 18:12:32 +00:00
|
|
|
InitializeCriticalSection(&m->mutex);
|
2015-03-24 19:14:49 +00:00
|
|
|
m->name = name;
|
|
|
|
#if NV_USE_TELEMETRY
|
|
|
|
tmLockName(tmContext, this, name);
|
|
|
|
#endif
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Mutex::~Mutex ()
|
|
|
|
{
|
2011-09-27 18:12:32 +00:00
|
|
|
DeleteCriticalSection(&m->mutex);
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Mutex::lock()
|
|
|
|
{
|
2018-02-06 02:55:07 +00:00
|
|
|
#if NV_USE_TELEMETRY3
|
|
|
|
tmStartWaitForLock(0, 0, this, m->name);
|
|
|
|
#elif NV_USE_TELEMETRY
|
2015-03-24 19:14:49 +00:00
|
|
|
TmU64 matcher;
|
|
|
|
tmTryLockEx(tmContext, &matcher, 100/*0.1 ms*/, __FILE__, __LINE__, this, "blocked");
|
|
|
|
#endif
|
|
|
|
|
2011-09-27 18:12:32 +00:00
|
|
|
EnterCriticalSection(&m->mutex);
|
2015-03-24 19:14:49 +00:00
|
|
|
|
2018-02-06 02:55:07 +00:00
|
|
|
#if NV_USE_TELEMETRY3
|
|
|
|
tmEndWaitForLock(0);
|
|
|
|
tmAcquiredLock(0, 0, this, m->name);
|
|
|
|
#elif NV_USE_TELEMETRY
|
2015-03-24 19:14:49 +00:00
|
|
|
tmEndTryLockEx(tmContext, matcher, __FILE__, __LINE__, this, TMLR_SUCCESS);
|
|
|
|
tmSetLockState(tmContext, this, TMLS_LOCKED, "acquired");
|
|
|
|
#endif
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Mutex::tryLock()
|
|
|
|
{
|
2018-02-06 02:55:07 +00:00
|
|
|
#if NV_USE_TELEMETRY3
|
|
|
|
tmStartWaitForLock(0, 0, this, m->name);
|
|
|
|
if (TryEnterCriticalSection(&m->mutex) != 0) {
|
|
|
|
tmEndWaitForLock(0);
|
|
|
|
tmAcquiredLock(0, 0, this, m->name);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tmEndWaitForLock(0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#elif NV_USE_TELEMETRY
|
2015-03-24 19:14:49 +00:00
|
|
|
TmU64 matcher;
|
|
|
|
tmTryLockEx(tmContext, &matcher, 100/*0.1 ms*/, __FILE__, __LINE__, this, "blocked");
|
|
|
|
if (TryEnterCriticalSection(&m->mutex) != 0) {
|
|
|
|
tmEndTryLockEx(tmContext, matcher, __FILE__, __LINE__, this, TMLR_SUCCESS);
|
|
|
|
tmSetLockState(tmContext, this, TMLS_LOCKED, "acquired");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tmEndTryLockEx(tmContext, matcher, __FILE__, __LINE__, this, TMLR_FAILED);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#else
|
2011-09-27 18:12:32 +00:00
|
|
|
return TryEnterCriticalSection(&m->mutex) != 0;
|
2015-03-24 19:14:49 +00:00
|
|
|
#endif
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Mutex::unlock()
|
|
|
|
{
|
2018-02-06 02:55:07 +00:00
|
|
|
#if NV_USE_TELEMETRY3
|
|
|
|
tmReleasedLock(0, this);
|
|
|
|
#elif NV_USE_TELEMETRY
|
2015-03-24 19:14:49 +00:00
|
|
|
tmSetLockState(tmContext, this, TMLS_RELEASED, "released");
|
|
|
|
#endif
|
|
|
|
|
2011-09-27 18:12:32 +00:00
|
|
|
LeaveCriticalSection(&m->mutex);
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
2013-06-07 17:53:55 +00:00
|
|
|
#elif NV_OS_USE_PTHREAD
|
2011-09-27 17:48:46 +00:00
|
|
|
|
|
|
|
struct Mutex::Private {
|
2011-09-27 18:12:32 +00:00
|
|
|
pthread_mutex_t mutex;
|
2018-02-06 02:55:07 +00:00
|
|
|
pthread_mutexattr_t attr;
|
2015-03-24 19:14:49 +00:00
|
|
|
const char * name;
|
2011-09-27 17:48:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-03-24 19:14:49 +00:00
|
|
|
Mutex::Mutex (const char * name) : m(new Private)
|
2011-09-27 17:48:46 +00:00
|
|
|
{
|
2018-02-06 02:55:07 +00:00
|
|
|
pthread_mutexattr_init(&m->attr);
|
|
|
|
pthread_mutexattr_settype(&m->attr, PTHREAD_MUTEX_RECURSIVE);
|
|
|
|
int result = pthread_mutex_init(&m->mutex, &m->attr);
|
|
|
|
//m->mutex = PTHREAD_MUTEX_INITIALIZER;
|
2015-03-24 19:14:49 +00:00
|
|
|
m->name = name;
|
2011-09-27 18:12:32 +00:00
|
|
|
nvDebugCheck(result == 0);
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Mutex::~Mutex ()
|
|
|
|
{
|
2011-09-27 18:12:32 +00:00
|
|
|
int result = pthread_mutex_destroy(&m->mutex);
|
|
|
|
nvDebugCheck(result == 0);
|
2018-02-06 02:55:07 +00:00
|
|
|
result = pthread_mutexattr_destroy(&m->attr);
|
|
|
|
nvDebugCheck(result == 0);
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Mutex::lock()
|
|
|
|
{
|
2011-09-27 18:12:32 +00:00
|
|
|
int result = pthread_mutex_lock(&m->mutex);
|
|
|
|
nvDebugCheck(result == 0);
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Mutex::tryLock()
|
|
|
|
{
|
2011-09-27 18:12:32 +00:00
|
|
|
int result = pthread_mutex_trylock(&m->mutex);
|
|
|
|
nvDebugCheck(result == 0 || result == EBUSY);
|
|
|
|
return result == 0;
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Mutex::unlock()
|
|
|
|
{
|
2011-09-27 18:12:32 +00:00
|
|
|
int result = pthread_mutex_unlock(&m->mutex);
|
|
|
|
nvDebugCheck(result == 0);
|
2011-09-27 17:48:46 +00:00
|
|
|
}
|
|
|
|
|
2011-09-27 18:12:32 +00:00
|
|
|
#endif // NV_OS_UNIX
|