16d6babf7SJonas Devlieghere //===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===// 26d6babf7SJonas Devlieghere // 36d6babf7SJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46d6babf7SJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 56d6babf7SJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66d6babf7SJonas Devlieghere // 76d6babf7SJonas Devlieghere //===----------------------------------------------------------------------===// 86d6babf7SJonas Devlieghere // 96d6babf7SJonas Devlieghere // This file implements the llvm::sys::RWMutex class. 106d6babf7SJonas Devlieghere // 116d6babf7SJonas Devlieghere //===----------------------------------------------------------------------===// 126d6babf7SJonas Devlieghere 136d6babf7SJonas Devlieghere #include "llvm/Support/Allocator.h" 146d6babf7SJonas Devlieghere #include "llvm/Support/RWMutex.h" 156d6babf7SJonas Devlieghere #include "llvm/Config/config.h" 166d6babf7SJonas Devlieghere 17*f4bdbea0SJonas Devlieghere #if defined(LLVM_USE_RW_MUTEX_IMPL) 186d6babf7SJonas Devlieghere using namespace llvm; 196d6babf7SJonas Devlieghere using namespace sys; 206d6babf7SJonas Devlieghere 216d6babf7SJonas Devlieghere #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 226d6babf7SJonas Devlieghere // Define all methods as no-ops if threading is explicitly disabled 236d6babf7SJonas Devlieghere 246d6babf7SJonas Devlieghere RWMutexImpl::RWMutexImpl() = default; 256d6babf7SJonas Devlieghere RWMutexImpl::~RWMutexImpl() = default; 266d6babf7SJonas Devlieghere lock_shared()276d6babf7SJonas Devliegherebool RWMutexImpl::lock_shared() { return true; } unlock_shared()286d6babf7SJonas Devliegherebool RWMutexImpl::unlock_shared() { return true; } lock()296d6babf7SJonas Devliegherebool RWMutexImpl::lock() { return true; } unlock()306d6babf7SJonas Devliegherebool RWMutexImpl::unlock() { return true; } 316d6babf7SJonas Devlieghere 326d6babf7SJonas Devlieghere #else 336d6babf7SJonas Devlieghere 346d6babf7SJonas Devlieghere #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT) 356d6babf7SJonas Devlieghere 366d6babf7SJonas Devlieghere #include <cassert> 376d6babf7SJonas Devlieghere #include <cstdlib> 386d6babf7SJonas Devlieghere #include <pthread.h> 396d6babf7SJonas Devlieghere 406d6babf7SJonas Devlieghere // Construct a RWMutex using pthread calls RWMutexImpl()416d6babf7SJonas DevlieghereRWMutexImpl::RWMutexImpl() 426d6babf7SJonas Devlieghere { 436d6babf7SJonas Devlieghere // Declare the pthread_rwlock data structures 446d6babf7SJonas Devlieghere pthread_rwlock_t* rwlock = 456d6babf7SJonas Devlieghere static_cast<pthread_rwlock_t*>(safe_malloc(sizeof(pthread_rwlock_t))); 466d6babf7SJonas Devlieghere 476d6babf7SJonas Devlieghere #ifdef __APPLE__ 486d6babf7SJonas Devlieghere // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init. 496d6babf7SJonas Devlieghere bzero(rwlock, sizeof(pthread_rwlock_t)); 506d6babf7SJonas Devlieghere #endif 516d6babf7SJonas Devlieghere 526d6babf7SJonas Devlieghere // Initialize the rwlock 536d6babf7SJonas Devlieghere int errorcode = pthread_rwlock_init(rwlock, nullptr); 546d6babf7SJonas Devlieghere (void)errorcode; 556d6babf7SJonas Devlieghere assert(errorcode == 0); 566d6babf7SJonas Devlieghere 576d6babf7SJonas Devlieghere // Assign the data member 586d6babf7SJonas Devlieghere data_ = rwlock; 596d6babf7SJonas Devlieghere } 606d6babf7SJonas Devlieghere 616d6babf7SJonas Devlieghere // Destruct a RWMutex ~RWMutexImpl()626d6babf7SJonas DevlieghereRWMutexImpl::~RWMutexImpl() 636d6babf7SJonas Devlieghere { 646d6babf7SJonas Devlieghere pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 656d6babf7SJonas Devlieghere assert(rwlock != nullptr); 666d6babf7SJonas Devlieghere pthread_rwlock_destroy(rwlock); 676d6babf7SJonas Devlieghere free(rwlock); 686d6babf7SJonas Devlieghere } 696d6babf7SJonas Devlieghere 706d6babf7SJonas Devlieghere bool lock_shared()716d6babf7SJonas DevlieghereRWMutexImpl::lock_shared() 726d6babf7SJonas Devlieghere { 736d6babf7SJonas Devlieghere pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 746d6babf7SJonas Devlieghere assert(rwlock != nullptr); 756d6babf7SJonas Devlieghere 766d6babf7SJonas Devlieghere int errorcode = pthread_rwlock_rdlock(rwlock); 776d6babf7SJonas Devlieghere return errorcode == 0; 786d6babf7SJonas Devlieghere } 796d6babf7SJonas Devlieghere 806d6babf7SJonas Devlieghere bool unlock_shared()816d6babf7SJonas DevlieghereRWMutexImpl::unlock_shared() 826d6babf7SJonas Devlieghere { 836d6babf7SJonas Devlieghere pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 846d6babf7SJonas Devlieghere assert(rwlock != nullptr); 856d6babf7SJonas Devlieghere 866d6babf7SJonas Devlieghere int errorcode = pthread_rwlock_unlock(rwlock); 876d6babf7SJonas Devlieghere return errorcode == 0; 886d6babf7SJonas Devlieghere } 896d6babf7SJonas Devlieghere 906d6babf7SJonas Devlieghere bool lock()916d6babf7SJonas DevlieghereRWMutexImpl::lock() 926d6babf7SJonas Devlieghere { 936d6babf7SJonas Devlieghere pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 946d6babf7SJonas Devlieghere assert(rwlock != nullptr); 956d6babf7SJonas Devlieghere 966d6babf7SJonas Devlieghere int errorcode = pthread_rwlock_wrlock(rwlock); 976d6babf7SJonas Devlieghere return errorcode == 0; 986d6babf7SJonas Devlieghere } 996d6babf7SJonas Devlieghere 1006d6babf7SJonas Devlieghere bool unlock()1016d6babf7SJonas DevlieghereRWMutexImpl::unlock() 1026d6babf7SJonas Devlieghere { 1036d6babf7SJonas Devlieghere pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 1046d6babf7SJonas Devlieghere assert(rwlock != nullptr); 1056d6babf7SJonas Devlieghere 1066d6babf7SJonas Devlieghere int errorcode = pthread_rwlock_unlock(rwlock); 1076d6babf7SJonas Devlieghere return errorcode == 0; 1086d6babf7SJonas Devlieghere } 1096d6babf7SJonas Devlieghere 1106d6babf7SJonas Devlieghere #else 1116d6babf7SJonas Devlieghere RWMutexImpl()1126d6babf7SJonas DevlieghereRWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { } 1136d6babf7SJonas Devlieghere ~RWMutexImpl()1146d6babf7SJonas DevlieghereRWMutexImpl::~RWMutexImpl() { 1156d6babf7SJonas Devlieghere delete static_cast<MutexImpl *>(data_); 1166d6babf7SJonas Devlieghere } 1176d6babf7SJonas Devlieghere lock_shared()1186d6babf7SJonas Devliegherebool RWMutexImpl::lock_shared() { 1196d6babf7SJonas Devlieghere return static_cast<MutexImpl *>(data_)->acquire(); 1206d6babf7SJonas Devlieghere } 1216d6babf7SJonas Devlieghere unlock_shared()1226d6babf7SJonas Devliegherebool RWMutexImpl::unlock_shared() { 1236d6babf7SJonas Devlieghere return static_cast<MutexImpl *>(data_)->release(); 1246d6babf7SJonas Devlieghere } 1256d6babf7SJonas Devlieghere lock()1266d6babf7SJonas Devliegherebool RWMutexImpl::lock() { 1276d6babf7SJonas Devlieghere return static_cast<MutexImpl *>(data_)->acquire(); 1286d6babf7SJonas Devlieghere } 1296d6babf7SJonas Devlieghere unlock()1306d6babf7SJonas Devliegherebool RWMutexImpl::unlock() { 1316d6babf7SJonas Devlieghere return static_cast<MutexImpl *>(data_)->release(); 1326d6babf7SJonas Devlieghere } 1336d6babf7SJonas Devlieghere 1346d6babf7SJonas Devlieghere #endif 1356d6babf7SJonas Devlieghere #endif 1366d6babf7SJonas Devlieghere #endif 137