1218885Sdim//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file implements the llvm::sys::Mutex class. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14218885Sdim#include "llvm/Config/config.h" 15218885Sdim#include "llvm/Support/Mutex.h" 16218885Sdim 17218885Sdim//===----------------------------------------------------------------------===// 18218885Sdim//=== WARNING: Implementation here must contain only TRULY operating system 19218885Sdim//=== independent code. 20218885Sdim//===----------------------------------------------------------------------===// 21218885Sdim 22234353Sdim#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 23218885Sdim// Define all methods as no-ops if threading is explicitly disabled 24218885Sdimnamespace llvm { 25218885Sdimusing namespace sys; 26218885SdimMutexImpl::MutexImpl( bool recursive) { } 27218885SdimMutexImpl::~MutexImpl() { } 28218885Sdimbool MutexImpl::acquire() { return true; } 29218885Sdimbool MutexImpl::release() { return true; } 30218885Sdimbool MutexImpl::tryacquire() { return true; } 31218885Sdim} 32218885Sdim#else 33218885Sdim 34218885Sdim#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK) 35218885Sdim 36218885Sdim#include <cassert> 37218885Sdim#include <pthread.h> 38218885Sdim#include <stdlib.h> 39218885Sdim 40218885Sdimnamespace llvm { 41218885Sdimusing namespace sys; 42218885Sdim 43218885Sdim// Construct a Mutex using pthread calls 44218885SdimMutexImpl::MutexImpl( bool recursive) 45218885Sdim : data_(0) 46218885Sdim{ 47234353Sdim // Declare the pthread_mutex data structures 48234353Sdim pthread_mutex_t* mutex = 49234353Sdim static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t))); 50234353Sdim pthread_mutexattr_t attr; 51218885Sdim 52234353Sdim // Initialize the mutex attributes 53234353Sdim int errorcode = pthread_mutexattr_init(&attr); 54234353Sdim assert(errorcode == 0); (void)errorcode; 55218885Sdim 56234353Sdim // Initialize the mutex as a recursive mutex, if requested, or normal 57234353Sdim // otherwise. 58234353Sdim int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL ); 59234353Sdim errorcode = pthread_mutexattr_settype(&attr, kind); 60234353Sdim assert(errorcode == 0); 61218885Sdim 62239462Sdim#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \ 63239462Sdim !defined(__DragonFly__) && !defined(__Bitrig__) 64234353Sdim // Make it a process local mutex 65234353Sdim errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); 66234353Sdim assert(errorcode == 0); 67218885Sdim#endif 68218885Sdim 69234353Sdim // Initialize the mutex 70234353Sdim errorcode = pthread_mutex_init(mutex, &attr); 71234353Sdim assert(errorcode == 0); 72218885Sdim 73234353Sdim // Destroy the attributes 74234353Sdim errorcode = pthread_mutexattr_destroy(&attr); 75234353Sdim assert(errorcode == 0); 76218885Sdim 77234353Sdim // Assign the data member 78234353Sdim data_ = mutex; 79218885Sdim} 80218885Sdim 81218885Sdim// Destruct a Mutex 82218885SdimMutexImpl::~MutexImpl() 83218885Sdim{ 84234353Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 85234353Sdim assert(mutex != 0); 86234353Sdim pthread_mutex_destroy(mutex); 87234353Sdim free(mutex); 88218885Sdim} 89218885Sdim 90218885Sdimbool 91218885SdimMutexImpl::acquire() 92218885Sdim{ 93234353Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 94234353Sdim assert(mutex != 0); 95218885Sdim 96234353Sdim int errorcode = pthread_mutex_lock(mutex); 97234353Sdim return errorcode == 0; 98218885Sdim} 99218885Sdim 100218885Sdimbool 101218885SdimMutexImpl::release() 102218885Sdim{ 103234353Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 104234353Sdim assert(mutex != 0); 105218885Sdim 106234353Sdim int errorcode = pthread_mutex_unlock(mutex); 107234353Sdim return errorcode == 0; 108218885Sdim} 109218885Sdim 110218885Sdimbool 111218885SdimMutexImpl::tryacquire() 112218885Sdim{ 113234353Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 114234353Sdim assert(mutex != 0); 115218885Sdim 116234353Sdim int errorcode = pthread_mutex_trylock(mutex); 117234353Sdim return errorcode == 0; 118218885Sdim} 119218885Sdim 120218885Sdim} 121218885Sdim 122218885Sdim#elif defined(LLVM_ON_UNIX) 123218885Sdim#include "Unix/Mutex.inc" 124218885Sdim#elif defined( LLVM_ON_WIN32) 125218885Sdim#include "Windows/Mutex.inc" 126218885Sdim#else 127226633Sdim#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp 128218885Sdim#endif 129218885Sdim#endif 130