[ThinLTO] Add code comment. NFC
[llvm-complete.git] / lib / Support / RWMutex.cpp
blob5accf73e5f9404ebffffc3d6a8e3b6f1928f3adf
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/Allocator.h"
14 #include "llvm/Support/RWMutex.h"
15 #include "llvm/Config/config.h"
17 #if defined(LLVM_USE_RW_MUTEX_IMPL)
18 using namespace llvm;
19 using namespace sys;
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; }
32 #else
34 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
36 #include <cassert>
37 #include <cstdlib>
38 #include <pthread.h>
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)));
47 #ifdef __APPLE__
48 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
49 bzero(rwlock, sizeof(pthread_rwlock_t));
50 #endif
52 // Initialize the rwlock
53 int errorcode = pthread_rwlock_init(rwlock, nullptr);
54 (void)errorcode;
55 assert(errorcode == 0);
57 // Assign the data member
58 data_ = rwlock;
61 // Destruct a RWMutex
62 RWMutexImpl::~RWMutexImpl()
64 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
65 assert(rwlock != nullptr);
66 pthread_rwlock_destroy(rwlock);
67 free(rwlock);
70 bool
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;
80 bool
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;
90 bool
91 RWMutexImpl::lock()
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;
100 bool
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;
110 #else
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();
134 #endif
135 #endif
136 #endif