1 //===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//
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-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the llvm::sys::RWMutex class.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Support/Allocator.h"
14 #include "llvm/Support/RWMutex.h"
15 #include "llvm/Config/config.h"
17 #if defined(LLVM_USE_RW_MUTEX_IMPL)
21 #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
22 // Define all methods as no-ops if threading is explicitly disabled
24 RWMutexImpl::RWMutexImpl() = default;
25 RWMutexImpl::~RWMutexImpl() = default;
27 bool RWMutexImpl::lock_shared() { return true; }
28 bool RWMutexImpl::unlock_shared() { return true; }
29 bool RWMutexImpl::lock() { return true; }
30 bool RWMutexImpl::unlock() { return true; }
34 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
40 // Construct a RWMutex using pthread calls
41 RWMutexImpl::RWMutexImpl()
43 // Declare the pthread_rwlock data structures
44 pthread_rwlock_t
* rwlock
=
45 static_cast<pthread_rwlock_t
*>(safe_malloc(sizeof(pthread_rwlock_t
)));
48 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
49 bzero(rwlock
, sizeof(pthread_rwlock_t
));
52 // Initialize the rwlock
53 int errorcode
= pthread_rwlock_init(rwlock
, nullptr);
55 assert(errorcode
== 0);
57 // Assign the data member
62 RWMutexImpl::~RWMutexImpl()
64 pthread_rwlock_t
* rwlock
= static_cast<pthread_rwlock_t
*>(data_
);
65 assert(rwlock
!= nullptr);
66 pthread_rwlock_destroy(rwlock
);
71 RWMutexImpl::lock_shared()
73 pthread_rwlock_t
* rwlock
= static_cast<pthread_rwlock_t
*>(data_
);
74 assert(rwlock
!= nullptr);
76 int errorcode
= pthread_rwlock_rdlock(rwlock
);
77 return errorcode
== 0;
81 RWMutexImpl::unlock_shared()
83 pthread_rwlock_t
* rwlock
= static_cast<pthread_rwlock_t
*>(data_
);
84 assert(rwlock
!= nullptr);
86 int errorcode
= pthread_rwlock_unlock(rwlock
);
87 return errorcode
== 0;
93 pthread_rwlock_t
* rwlock
= static_cast<pthread_rwlock_t
*>(data_
);
94 assert(rwlock
!= nullptr);
96 int errorcode
= pthread_rwlock_wrlock(rwlock
);
97 return errorcode
== 0;
101 RWMutexImpl::unlock()
103 pthread_rwlock_t
* rwlock
= static_cast<pthread_rwlock_t
*>(data_
);
104 assert(rwlock
!= nullptr);
106 int errorcode
= pthread_rwlock_unlock(rwlock
);
107 return errorcode
== 0;
112 RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { }
114 RWMutexImpl::~RWMutexImpl() {
115 delete static_cast<MutexImpl
*>(data_
);
118 bool RWMutexImpl::lock_shared() {
119 return static_cast<MutexImpl
*>(data_
)->acquire();
122 bool RWMutexImpl::unlock_shared() {
123 return static_cast<MutexImpl
*>(data_
)->release();
126 bool RWMutexImpl::lock() {
127 return static_cast<MutexImpl
*>(data_
)->acquire();
130 bool RWMutexImpl::unlock() {
131 return static_cast<MutexImpl
*>(data_
)->release();