1 //===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the llvm::sys::Mutex class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Support/Mutex.h" 15 #include "llvm/Support/ErrorHandling.h" 16 #include "llvm/Config/config.h" 17 18 //===----------------------------------------------------------------------===// 19 //=== WARNING: Implementation here must contain only TRULY operating system 20 //=== independent code. 21 //===----------------------------------------------------------------------===// 22 23 #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 24 // Define all methods as no-ops if threading is explicitly disabled 25 namespace llvm { 26 using namespace sys; 27 MutexImpl::MutexImpl( bool recursive) { } 28 MutexImpl::~MutexImpl() { } 29 bool MutexImpl::acquire() { return true; } 30 bool MutexImpl::release() { return true; } 31 bool MutexImpl::tryacquire() { return true; } 32 } 33 #else 34 35 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK) 36 37 #include <cassert> 38 #include <pthread.h> 39 #include <stdlib.h> 40 41 namespace llvm { 42 using namespace sys; 43 44 // Construct a Mutex using pthread calls 45 MutexImpl::MutexImpl( bool recursive) 46 : data_(nullptr) 47 { 48 // Declare the pthread_mutex data structures 49 pthread_mutex_t* mutex = 50 static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t))); 51 52 if (mutex == nullptr) 53 report_bad_alloc_error("Mutex allocation failed"); 54 55 pthread_mutexattr_t attr; 56 57 // Initialize the mutex attributes 58 int errorcode = pthread_mutexattr_init(&attr); 59 assert(errorcode == 0); (void)errorcode; 60 61 // Initialize the mutex as a recursive mutex, if requested, or normal 62 // otherwise. 63 int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL ); 64 errorcode = pthread_mutexattr_settype(&attr, kind); 65 assert(errorcode == 0); 66 67 // Initialize the mutex 68 errorcode = pthread_mutex_init(mutex, &attr); 69 assert(errorcode == 0); 70 71 // Destroy the attributes 72 errorcode = pthread_mutexattr_destroy(&attr); 73 assert(errorcode == 0); 74 75 // Assign the data member 76 data_ = mutex; 77 } 78 79 // Destruct a Mutex 80 MutexImpl::~MutexImpl() 81 { 82 pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 83 assert(mutex != nullptr); 84 pthread_mutex_destroy(mutex); 85 free(mutex); 86 } 87 88 bool 89 MutexImpl::acquire() 90 { 91 pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 92 assert(mutex != nullptr); 93 94 int errorcode = pthread_mutex_lock(mutex); 95 return errorcode == 0; 96 } 97 98 bool 99 MutexImpl::release() 100 { 101 pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 102 assert(mutex != nullptr); 103 104 int errorcode = pthread_mutex_unlock(mutex); 105 return errorcode == 0; 106 } 107 108 bool 109 MutexImpl::tryacquire() 110 { 111 pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); 112 assert(mutex != nullptr); 113 114 int errorcode = pthread_mutex_trylock(mutex); 115 return errorcode == 0; 116 } 117 118 } 119 120 #elif defined(LLVM_ON_UNIX) 121 #include "Unix/Mutex.inc" 122 #elif defined( LLVM_ON_WIN32) 123 #include "Windows/Mutex.inc" 124 #else 125 #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp 126 #endif 127 #endif 128