LLVM API Documentation
00001 //===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the llvm::sys::RWMutex class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Config/config.h" 00015 #include "llvm/Support/RWMutex.h" 00016 #include <cstring> 00017 00018 //===----------------------------------------------------------------------===// 00019 //=== WARNING: Implementation here must contain only TRULY operating system 00020 //=== independent code. 00021 //===----------------------------------------------------------------------===// 00022 00023 #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 00024 // Define all methods as no-ops if threading is explicitly disabled 00025 namespace llvm { 00026 using namespace sys; 00027 RWMutexImpl::RWMutexImpl() { } 00028 RWMutexImpl::~RWMutexImpl() { } 00029 bool RWMutexImpl::reader_acquire() { return true; } 00030 bool RWMutexImpl::reader_release() { return true; } 00031 bool RWMutexImpl::writer_acquire() { return true; } 00032 bool RWMutexImpl::writer_release() { return true; } 00033 } 00034 #else 00035 00036 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT) 00037 00038 #include <cassert> 00039 #include <pthread.h> 00040 #include <stdlib.h> 00041 00042 namespace llvm { 00043 using namespace sys; 00044 00045 // Construct a RWMutex using pthread calls 00046 RWMutexImpl::RWMutexImpl() 00047 : data_(nullptr) 00048 { 00049 // Declare the pthread_rwlock data structures 00050 pthread_rwlock_t* rwlock = 00051 static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t))); 00052 00053 #ifdef __APPLE__ 00054 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init. 00055 bzero(rwlock, sizeof(pthread_rwlock_t)); 00056 #endif 00057 00058 // Initialize the rwlock 00059 int errorcode = pthread_rwlock_init(rwlock, nullptr); 00060 (void)errorcode; 00061 assert(errorcode == 0); 00062 00063 // Assign the data member 00064 data_ = rwlock; 00065 } 00066 00067 // Destruct a RWMutex 00068 RWMutexImpl::~RWMutexImpl() 00069 { 00070 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 00071 assert(rwlock != nullptr); 00072 pthread_rwlock_destroy(rwlock); 00073 free(rwlock); 00074 } 00075 00076 bool 00077 RWMutexImpl::reader_acquire() 00078 { 00079 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 00080 assert(rwlock != nullptr); 00081 00082 int errorcode = pthread_rwlock_rdlock(rwlock); 00083 return errorcode == 0; 00084 } 00085 00086 bool 00087 RWMutexImpl::reader_release() 00088 { 00089 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 00090 assert(rwlock != nullptr); 00091 00092 int errorcode = pthread_rwlock_unlock(rwlock); 00093 return errorcode == 0; 00094 } 00095 00096 bool 00097 RWMutexImpl::writer_acquire() 00098 { 00099 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 00100 assert(rwlock != nullptr); 00101 00102 int errorcode = pthread_rwlock_wrlock(rwlock); 00103 return errorcode == 0; 00104 } 00105 00106 bool 00107 RWMutexImpl::writer_release() 00108 { 00109 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 00110 assert(rwlock != nullptr); 00111 00112 int errorcode = pthread_rwlock_unlock(rwlock); 00113 return errorcode == 0; 00114 } 00115 00116 } 00117 00118 #elif defined(LLVM_ON_UNIX) 00119 #include "Unix/RWMutex.inc" 00120 #elif defined( LLVM_ON_WIN32) 00121 #include "Windows/RWMutex.inc" 00122 #else 00123 #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp 00124 #endif 00125 #endif