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