Mutex.cpp revision 218885
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 22218885Sdim#if !defined(ENABLE_THREADS) || 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 44218885Sdim// This variable is useful for situations where the pthread library has been 45218885Sdim// compiled with weak linkage for its interface symbols. This allows the 46218885Sdim// threading support to be turned off by simply not linking against -lpthread. 47218885Sdim// In that situation, the value of pthread_mutex_init will be 0 and 48218885Sdim// consequently pthread_enabled will be false. In such situations, all the 49218885Sdim// pthread operations become no-ops and the functions all return false. If 50218885Sdim// pthread_mutex_init does have an address, then mutex support is enabled. 51218885Sdim// Note: all LLVM tools will link against -lpthread if its available since it 52218885Sdim// is configured into the LIBS variable. 53218885Sdim// Note: this line of code generates a warning if pthread_mutex_init is not 54218885Sdim// declared with weak linkage. It's safe to ignore the warning. 55218885Sdimstatic const bool pthread_enabled = true; 56218885Sdim 57218885Sdim// Construct a Mutex using pthread calls 58218885SdimMutexImpl::MutexImpl( bool recursive) 59218885Sdim : data_(0) 60218885Sdim{ 61218885Sdim if (pthread_enabled) 62218885Sdim { 63218885Sdim // Declare the pthread_mutex data structures 64218885Sdim pthread_mutex_t* mutex = 65218885Sdim static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t))); 66218885Sdim pthread_mutexattr_t attr; 67218885Sdim 68218885Sdim // Initialize the mutex attributes 69218885Sdim int errorcode = pthread_mutexattr_init(&attr); 70218885Sdim assert(errorcode == 0); 71218885Sdim 72218885Sdim // Initialize the mutex as a recursive mutex, if requested, or normal 73218885Sdim // otherwise. 74218885Sdim int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL ); 75218885Sdim errorcode = pthread_mutexattr_settype(&attr, kind); 76218885Sdim assert(errorcode == 0); 77218885Sdim 78218885Sdim#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) 79218885Sdim // Make it a process local mutex 80218885Sdim errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); 81218885Sdim assert(errorcode == 0); 82218885Sdim#endif 83218885Sdim 84218885Sdim // Initialize the mutex 85218885Sdim errorcode = pthread_mutex_init(mutex, &attr); 86218885Sdim assert(errorcode == 0); 87218885Sdim 88218885Sdim // Destroy the attributes 89218885Sdim errorcode = pthread_mutexattr_destroy(&attr); 90218885Sdim assert(errorcode == 0); 91218885Sdim 92218885Sdim // Assign the data member 93218885Sdim data_ = mutex; 94218885Sdim } 95218885Sdim} 96218885Sdim 97218885Sdim// Destruct a Mutex 98218885SdimMutexImpl::~MutexImpl() 99218885Sdim{ 100218885Sdim if (pthread_enabled) 101218885Sdim { 102218885Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 103218885Sdim assert(mutex != 0); 104218885Sdim pthread_mutex_destroy(mutex); 105218885Sdim free(mutex); 106218885Sdim } 107218885Sdim} 108218885Sdim 109218885Sdimbool 110218885SdimMutexImpl::acquire() 111218885Sdim{ 112218885Sdim if (pthread_enabled) 113218885Sdim { 114218885Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 115218885Sdim assert(mutex != 0); 116218885Sdim 117218885Sdim int errorcode = pthread_mutex_lock(mutex); 118218885Sdim return errorcode == 0; 119218885Sdim } else return false; 120218885Sdim} 121218885Sdim 122218885Sdimbool 123218885SdimMutexImpl::release() 124218885Sdim{ 125218885Sdim if (pthread_enabled) 126218885Sdim { 127218885Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 128218885Sdim assert(mutex != 0); 129218885Sdim 130218885Sdim int errorcode = pthread_mutex_unlock(mutex); 131218885Sdim return errorcode == 0; 132218885Sdim } else return false; 133218885Sdim} 134218885Sdim 135218885Sdimbool 136218885SdimMutexImpl::tryacquire() 137218885Sdim{ 138218885Sdim if (pthread_enabled) 139218885Sdim { 140218885Sdim pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 141218885Sdim assert(mutex != 0); 142218885Sdim 143218885Sdim int errorcode = pthread_mutex_trylock(mutex); 144218885Sdim return errorcode == 0; 145218885Sdim } else return false; 146218885Sdim} 147218885Sdim 148218885Sdim} 149218885Sdim 150218885Sdim#elif defined(LLVM_ON_UNIX) 151218885Sdim#include "Unix/Mutex.inc" 152218885Sdim#elif defined( LLVM_ON_WIN32) 153218885Sdim#include "Windows/Mutex.inc" 154218885Sdim#else 155218885Sdim#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp 156218885Sdim#endif 157218885Sdim#endif 158