LLVM API Documentation
00001 //===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Reid Spencer and is distributed under the 00006 // University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the llvm::sys::Mutex class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Config/config.h" 00015 #include "llvm/System/Mutex.h" 00016 00017 //===----------------------------------------------------------------------===// 00018 //=== WARNING: Implementation here must contain only TRULY operating system 00019 //=== independent code. 00020 //===----------------------------------------------------------------------===// 00021 00022 #if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0 00023 // Define all methods as no-ops if threading is explicitly disabled 00024 namespace llvm { 00025 using namespace sys; 00026 Mutex::Mutex( bool recursive) { } 00027 Mutex::~Mutex() { } 00028 bool Mutex::acquire() { return true; } 00029 bool Mutex::release() { return true; } 00030 bool Mutex::tryacquire() { return true; } 00031 } 00032 #else 00033 00034 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK) 00035 00036 #include <cassert> 00037 #include <pthread.h> 00038 #include <stdlib.h> 00039 00040 namespace llvm { 00041 using namespace sys; 00042 00043 00044 // This variable is useful for situations where the pthread library has been 00045 // compiled with weak linkage for its interface symbols. This allows the 00046 // threading support to be turned off by simply not linking against -lpthread. 00047 // In that situation, the value of pthread_mutex_init will be 0 and 00048 // consequently pthread_enabled will be false. In such situations, all the 00049 // pthread operations become no-ops and the functions all return false. If 00050 // pthread_mutex_init does have an address, then mutex support is enabled. 00051 // Note: all LLVM tools will link against -lpthread if its available since it 00052 // is configured into the LIBS variable. 00053 // Note: this line of code generates a warning if pthread_mutex_init is not 00054 // declared with weak linkage. It's safe to ignore the warning. 00055 static const bool pthread_enabled = static_cast<bool>(pthread_mutex_init); 00056 00057 // Construct a Mutex using pthread calls 00058 Mutex::Mutex( bool recursive) 00059 : data_(0) 00060 { 00061 if (pthread_enabled) 00062 { 00063 // Declare the pthread_mutex data structures 00064 pthread_mutex_t* mutex = 00065 static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t))); 00066 pthread_mutexattr_t attr; 00067 00068 // Initialize the mutex attributes 00069 int errorcode = pthread_mutexattr_init(&attr); 00070 assert(errorcode == 0); 00071 00072 // Initialize the mutex as a recursive mutex, if requested, or normal 00073 // otherwise. 00074 int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL ); 00075 errorcode = pthread_mutexattr_settype(&attr, kind); 00076 assert(errorcode == 0); 00077 00078 #ifndef __FreeBSD__ 00079 // Make it a process local mutex 00080 errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); 00081 #endif 00082 00083 // Initialize the mutex 00084 errorcode = pthread_mutex_init(mutex, &attr); 00085 assert(errorcode == 0); 00086 00087 // Destroy the attributes 00088 errorcode = pthread_mutexattr_destroy(&attr); 00089 assert(errorcode == 0); 00090 00091 // Assign the data member 00092 data_ = mutex; 00093 } 00094 } 00095 00096 // Destruct a Mutex 00097 Mutex::~Mutex() 00098 { 00099 if (pthread_enabled) 00100 { 00101 pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_); 00102 assert(mutex != 0); 00103 int errorcode = pthread_mutex_destroy(mutex); 00104 assert(mutex != 0); 00105 } 00106 } 00107 00108 bool 00109 Mutex::acquire() 00110 { 00111 if (pthread_enabled) 00112 { 00113 pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_); 00114 assert(mutex != 0); 00115 00116 int errorcode = pthread_mutex_lock(mutex); 00117 return errorcode == 0; 00118 } 00119 return false; 00120 } 00121 00122 bool 00123 Mutex::release() 00124 { 00125 if (pthread_enabled) 00126 { 00127 pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_); 00128 assert(mutex != 0); 00129 00130 int errorcode = pthread_mutex_unlock(mutex); 00131 return errorcode == 0; 00132 } 00133 return false; 00134 } 00135 00136 bool 00137 Mutex::tryacquire() 00138 { 00139 if (pthread_enabled) 00140 { 00141 pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_); 00142 assert(mutex != 0); 00143 00144 int errorcode = pthread_mutex_trylock(mutex); 00145 return errorcode == 0; 00146 } 00147 return false; 00148 } 00149 00150 } 00151 00152 #elif defined(LLVM_ON_UNIX) 00153 #include "Unix/Mutex.inc" 00154 #elif defined( LLVM_ON_WIN32) 00155 #include "Win32/Mutex.inc" 00156 #else 00157 #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp 00158 #endif 00159 #endif