forked from OSchip/llvm-project
149 lines
3.4 KiB
C
149 lines
3.4 KiB
C
|
//===-- PThreadMutex.h ------------------------------------------*- C++ -*-===//
|
||
|
//
|
||
|
// The LLVM Compiler Infrastructure
|
||
|
//
|
||
|
// This file is distributed under the University of Illinois Open Source
|
||
|
// License. See LICENSE.TXT for details.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
//
|
||
|
// Created by Greg Clayton on 6/16/07.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#ifndef __PThreadMutex_h__
|
||
|
#define __PThreadMutex_h__
|
||
|
|
||
|
#include <pthread.h>
|
||
|
#include <assert.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
//#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1
|
||
|
|
||
|
#if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS)
|
||
|
#define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__)
|
||
|
|
||
|
#else
|
||
|
#define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex)
|
||
|
#endif
|
||
|
|
||
|
class PThreadMutex
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
class Locker
|
||
|
{
|
||
|
public:
|
||
|
#if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS)
|
||
|
|
||
|
Locker(PThreadMutex& m, const char *function, const char *file, int line);
|
||
|
Locker(PThreadMutex* m, const char *function, const char *file, int line);
|
||
|
Locker(pthread_mutex_t *mutex, const char *function, const char *file, int line);
|
||
|
~Locker();
|
||
|
void Lock();
|
||
|
void Unlock();
|
||
|
|
||
|
#else
|
||
|
Locker(PThreadMutex& m) :
|
||
|
m_pMutex(m.Mutex())
|
||
|
{
|
||
|
Lock();
|
||
|
}
|
||
|
|
||
|
Locker(PThreadMutex* m) :
|
||
|
m_pMutex(m ? m->Mutex() : NULL)
|
||
|
{
|
||
|
Lock();
|
||
|
}
|
||
|
|
||
|
Locker(pthread_mutex_t *mutex) :
|
||
|
m_pMutex(mutex)
|
||
|
{
|
||
|
Lock();
|
||
|
}
|
||
|
|
||
|
void Lock()
|
||
|
{
|
||
|
if (m_pMutex)
|
||
|
::pthread_mutex_lock (m_pMutex);
|
||
|
}
|
||
|
|
||
|
void Unlock()
|
||
|
{
|
||
|
if (m_pMutex)
|
||
|
::pthread_mutex_unlock (m_pMutex);
|
||
|
}
|
||
|
|
||
|
~Locker()
|
||
|
{
|
||
|
Unlock();
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
// unlock any the current mutex and lock the new one if it is valid
|
||
|
void Reset(pthread_mutex_t *pMutex = NULL)
|
||
|
{
|
||
|
Unlock();
|
||
|
m_pMutex = pMutex;
|
||
|
Lock();
|
||
|
}
|
||
|
pthread_mutex_t *m_pMutex;
|
||
|
#if defined (DEBUG_PTHREAD_MUTEX_DEADLOCKS)
|
||
|
const char *m_function;
|
||
|
const char *m_file;
|
||
|
int m_line;
|
||
|
uint64_t m_lock_time;
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
|
||
|
PThreadMutex()
|
||
|
{
|
||
|
int err;
|
||
|
err = ::pthread_mutex_init (&m_mutex, NULL); assert(err == 0);
|
||
|
}
|
||
|
|
||
|
PThreadMutex(int type)
|
||
|
{
|
||
|
int err;
|
||
|
::pthread_mutexattr_t attr;
|
||
|
err = ::pthread_mutexattr_init (&attr); assert(err == 0);
|
||
|
err = ::pthread_mutexattr_settype (&attr, type); assert(err == 0);
|
||
|
err = ::pthread_mutex_init (&m_mutex, &attr); assert(err == 0);
|
||
|
err = ::pthread_mutexattr_destroy (&attr); assert(err == 0);
|
||
|
}
|
||
|
|
||
|
~PThreadMutex()
|
||
|
{
|
||
|
int err;
|
||
|
err = ::pthread_mutex_destroy (&m_mutex);
|
||
|
if (err != 0)
|
||
|
{
|
||
|
err = Unlock();
|
||
|
if (err == 0)
|
||
|
::pthread_mutex_destroy (&m_mutex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pthread_mutex_t *Mutex()
|
||
|
{
|
||
|
return &m_mutex;
|
||
|
}
|
||
|
|
||
|
int Lock()
|
||
|
{
|
||
|
return ::pthread_mutex_lock (&m_mutex);
|
||
|
}
|
||
|
|
||
|
int Unlock()
|
||
|
{
|
||
|
return ::pthread_mutex_unlock (&m_mutex);
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
pthread_mutex_t m_mutex;
|
||
|
};
|
||
|
|
||
|
#endif
|