[clang] Add test for CWG190 "Layout-compatible POD-struct types" (#121668)
[llvm-project.git] / llvm / lib / Support / RWMutex.cpp
blob4294c4356f4762d478ecff0300756945ca5f38c9
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.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Support/RWMutex.h"
14 #include "llvm/Config/config.h"
15 #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
16 #include "llvm/Support/Allocator.h"
18 #if defined(LLVM_USE_RW_MUTEX_IMPL)
19 using namespace llvm;
20 using namespace sys;
22 #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
23 // Define all methods as no-ops if threading is explicitly disabled
25 RWMutexImpl::RWMutexImpl() = default;
26 RWMutexImpl::~RWMutexImpl() = default;
28 bool RWMutexImpl::lock_shared() { return true; }
29 bool RWMutexImpl::unlock_shared() { return true; }
30 bool RWMutexImpl::try_lock_shared() { return true; }
31 bool RWMutexImpl::lock() { return true; }
32 bool RWMutexImpl::unlock() { return true; }
33 bool RWMutexImpl::try_lock() { return true; }
35 #else
37 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
39 #include <cassert>
40 #include <cstdlib>
41 #include <pthread.h>
43 // Construct a RWMutex using pthread calls
44 RWMutexImpl::RWMutexImpl()
46 // Declare the pthread_rwlock data structures
47 pthread_rwlock_t* rwlock =
48 static_cast<pthread_rwlock_t*>(safe_malloc(sizeof(pthread_rwlock_t)));
50 #ifdef __APPLE__
51 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
52 bzero(rwlock, sizeof(pthread_rwlock_t));
53 #endif
55 // Initialize the rwlock
56 int errorcode = pthread_rwlock_init(rwlock, nullptr);
57 (void)errorcode;
58 assert(errorcode == 0);
60 // Assign the data member
61 data_ = rwlock;
64 // Destruct a RWMutex
65 RWMutexImpl::~RWMutexImpl()
67 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
68 assert(rwlock != nullptr);
69 pthread_rwlock_destroy(rwlock);
70 free(rwlock);
73 bool
74 RWMutexImpl::lock_shared()
76 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
77 assert(rwlock != nullptr);
79 int errorcode = pthread_rwlock_rdlock(rwlock);
80 return errorcode == 0;
83 bool
84 RWMutexImpl::unlock_shared()
86 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
87 assert(rwlock != nullptr);
89 int errorcode = pthread_rwlock_unlock(rwlock);
90 return errorcode == 0;
93 bool RWMutexImpl::try_lock_shared() {
94 pthread_rwlock_t *rwlock = static_cast<pthread_rwlock_t *>(data_);
95 assert(rwlock != nullptr);
97 int errorcode = pthread_rwlock_tryrdlock(rwlock);
98 return errorcode == 0;
101 bool
102 RWMutexImpl::lock()
104 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
105 assert(rwlock != nullptr);
107 int errorcode = pthread_rwlock_wrlock(rwlock);
108 return errorcode == 0;
111 bool
112 RWMutexImpl::unlock()
114 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
115 assert(rwlock != nullptr);
117 int errorcode = pthread_rwlock_unlock(rwlock);
118 return errorcode == 0;
121 bool RWMutexImpl::try_lock() {
122 pthread_rwlock_t *rwlock = static_cast<pthread_rwlock_t *>(data_);
123 assert(rwlock != nullptr);
125 int errorcode = pthread_rwlock_trywrlock(rwlock);
126 return errorcode == 0;
129 #else
131 RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { }
133 RWMutexImpl::~RWMutexImpl() {
134 delete static_cast<MutexImpl *>(data_);
137 bool RWMutexImpl::lock_shared() {
138 return static_cast<MutexImpl *>(data_)->acquire();
141 bool RWMutexImpl::unlock_shared() {
142 return static_cast<MutexImpl *>(data_)->release();
145 bool RWMutexImpl::try_lock_shared() {
146 return static_cast<MutexImpl *>(data_)->tryacquire();
149 bool RWMutexImpl::lock() {
150 return static_cast<MutexImpl *>(data_)->acquire();
153 bool RWMutexImpl::unlock() {
154 return static_cast<MutexImpl *>(data_)->release();
157 bool RWMutexImpl::try_lock() {
158 return static_cast<MutexImpl *>(data_)->tryacquire();
161 #endif
162 #endif
163 #endif