164 lines · cpp
1//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the llvm::sys::RWMutex class.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Support/RWMutex.h"14#include "llvm/Config/config.h"15#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS16#include "llvm/Support/Allocator.h"17 18#if defined(LLVM_USE_RW_MUTEX_IMPL)19using namespace llvm;20using namespace sys;21 22#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 023// Define all methods as no-ops if threading is explicitly disabled24 25RWMutexImpl::RWMutexImpl() = default;26RWMutexImpl::~RWMutexImpl() = default;27 28bool RWMutexImpl::lock_shared() { return true; }29bool RWMutexImpl::unlock_shared() { return true; }30bool RWMutexImpl::try_lock_shared() { return true; }31bool RWMutexImpl::lock() { return true; }32bool RWMutexImpl::unlock() { return true; }33bool RWMutexImpl::try_lock() { return true; }34 35#else36 37#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)38 39#include <cassert>40#include <cstdlib>41#include <pthread.h>42 43// Construct a RWMutex using pthread calls44RWMutexImpl::RWMutexImpl()45{46 // Declare the pthread_rwlock data structures47 pthread_rwlock_t* rwlock =48 static_cast<pthread_rwlock_t*>(safe_malloc(sizeof(pthread_rwlock_t)));49 50#ifdef __APPLE__51 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.52 bzero(rwlock, sizeof(pthread_rwlock_t));53#endif54 55 // Initialize the rwlock56 int errorcode = pthread_rwlock_init(rwlock, nullptr);57 (void)errorcode;58 assert(errorcode == 0);59 60 // Assign the data member61 data_ = rwlock;62}63 64// Destruct a RWMutex65RWMutexImpl::~RWMutexImpl()66{67 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);68 assert(rwlock != nullptr);69 pthread_rwlock_destroy(rwlock);70 free(rwlock);71}72 73bool74RWMutexImpl::lock_shared()75{76 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);77 assert(rwlock != nullptr);78 79 int errorcode = pthread_rwlock_rdlock(rwlock);80 return errorcode == 0;81}82 83bool84RWMutexImpl::unlock_shared()85{86 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);87 assert(rwlock != nullptr);88 89 int errorcode = pthread_rwlock_unlock(rwlock);90 return errorcode == 0;91}92 93bool RWMutexImpl::try_lock_shared() {94 pthread_rwlock_t *rwlock = static_cast<pthread_rwlock_t *>(data_);95 assert(rwlock != nullptr);96 97 int errorcode = pthread_rwlock_tryrdlock(rwlock);98 return errorcode == 0;99}100 101bool102RWMutexImpl::lock()103{104 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);105 assert(rwlock != nullptr);106 107 int errorcode = pthread_rwlock_wrlock(rwlock);108 return errorcode == 0;109}110 111bool112RWMutexImpl::unlock()113{114 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);115 assert(rwlock != nullptr);116 117 int errorcode = pthread_rwlock_unlock(rwlock);118 return errorcode == 0;119}120 121bool RWMutexImpl::try_lock() {122 pthread_rwlock_t *rwlock = static_cast<pthread_rwlock_t *>(data_);123 assert(rwlock != nullptr);124 125 int errorcode = pthread_rwlock_trywrlock(rwlock);126 return errorcode == 0;127}128 129#else130 131RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { }132 133RWMutexImpl::~RWMutexImpl() {134 delete static_cast<MutexImpl *>(data_);135}136 137bool RWMutexImpl::lock_shared() {138 return static_cast<MutexImpl *>(data_)->acquire();139}140 141bool RWMutexImpl::unlock_shared() {142 return static_cast<MutexImpl *>(data_)->release();143}144 145bool RWMutexImpl::try_lock_shared() {146 return static_cast<MutexImpl *>(data_)->tryacquire();147}148 149bool RWMutexImpl::lock() {150 return static_cast<MutexImpl *>(data_)->acquire();151}152 153bool RWMutexImpl::unlock() {154 return static_cast<MutexImpl *>(data_)->release();155}156 157bool RWMutexImpl::try_lock() {158 return static_cast<MutexImpl *>(data_)->tryacquire();159}160 161#endif162#endif163#endif164