1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | //===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the llvm::sys::RWMutex class. // //===----------------------------------------------------------------------===// #include "llvm/Support/Allocator.h" #include "llvm/Support/RWMutex.h" #include "llvm/Config/config.h" //===----------------------------------------------------------------------===// //=== WARNING: Implementation here must contain only TRULY operating system //=== independent code. //===----------------------------------------------------------------------===// #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 // Define all methods as no-ops if threading is explicitly disabled using namespace llvm; using namespace sys; RWMutexImpl::RWMutexImpl() = default; RWMutexImpl::~RWMutexImpl() = default; bool RWMutexImpl::reader_acquire() { return true; } bool RWMutexImpl::reader_release() { return true; } bool RWMutexImpl::writer_acquire() { return true; } bool RWMutexImpl::writer_release() { return true; } #else #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT) #include <cassert> #include <cstdlib> #include <pthread.h> using namespace llvm; using namespace sys; // Construct a RWMutex using pthread calls RWMutexImpl::RWMutexImpl() { // Declare the pthread_rwlock data structures pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(safe_malloc(sizeof(pthread_rwlock_t))); #ifdef __APPLE__ // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init. bzero(rwlock, sizeof(pthread_rwlock_t)); #endif // Initialize the rwlock int errorcode = pthread_rwlock_init(rwlock, nullptr); (void)errorcode; assert(errorcode == 0); // Assign the data member data_ = rwlock; } // Destruct a RWMutex RWMutexImpl::~RWMutexImpl() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); pthread_rwlock_destroy(rwlock); free(rwlock); } bool RWMutexImpl::reader_acquire() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); int errorcode = pthread_rwlock_rdlock(rwlock); return errorcode == 0; } bool RWMutexImpl::reader_release() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); int errorcode = pthread_rwlock_unlock(rwlock); return errorcode == 0; } bool RWMutexImpl::writer_acquire() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); int errorcode = pthread_rwlock_wrlock(rwlock); return errorcode == 0; } bool RWMutexImpl::writer_release() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); int errorcode = pthread_rwlock_unlock(rwlock); return errorcode == 0; } #elif defined(LLVM_ON_UNIX) #include "Unix/RWMutex.inc" #elif defined( _WIN32) #include "Windows/RWMutex.inc" #else #warning Neither LLVM_ON_UNIX nor _WIN32 was set in Support/Mutex.cpp #endif #endif |