LLVM 20.0.0git
RWMutex.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the llvm::sys::RWMutex class.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/Config/config.h"
15#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
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 == 0
23// Define all methods as no-ops if threading is explicitly disabled
24
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#else
36
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 calls
44RWMutexImpl::RWMutexImpl()
45{
46 // Declare the pthread_rwlock data structures
47 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#endif
54
55 // Initialize the rwlock
56 int errorcode = pthread_rwlock_init(rwlock, nullptr);
57 (void)errorcode;
58 assert(errorcode == 0);
59
60 // Assign the data member
61 data_ = rwlock;
62}
63
64// Destruct a RWMutex
65RWMutexImpl::~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
73bool
74RWMutexImpl::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
83bool
84RWMutexImpl::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
101bool
102RWMutexImpl::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
111bool
112RWMutexImpl::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#else
130
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#endif
162#endif
163#endif
This file defines the BumpPtrAllocator interface.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
Definition: MemAlloc.h:25