150
|
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
|
|
13 #include "llvm/Support/Allocator.h"
|
|
14 #include "llvm/Support/RWMutex.h"
|
|
15 #include "llvm/Config/config.h"
|
|
16
|
|
17 #if defined(LLVM_USE_RW_MUTEX_IMPL)
|
|
18 using namespace llvm;
|
|
19 using namespace sys;
|
|
20
|
|
21 #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
|
|
22 // Define all methods as no-ops if threading is explicitly disabled
|
|
23
|
|
24 RWMutexImpl::RWMutexImpl() = default;
|
|
25 RWMutexImpl::~RWMutexImpl() = default;
|
|
26
|
|
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; }
|
|
31
|
|
32 #else
|
|
33
|
|
34 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
|
|
35
|
|
36 #include <cassert>
|
|
37 #include <cstdlib>
|
|
38 #include <pthread.h>
|
|
39
|
|
40 // Construct a RWMutex using pthread calls
|
|
41 RWMutexImpl::RWMutexImpl()
|
|
42 {
|
|
43 // Declare the pthread_rwlock data structures
|
|
44 pthread_rwlock_t* rwlock =
|
|
45 static_cast<pthread_rwlock_t*>(safe_malloc(sizeof(pthread_rwlock_t)));
|
|
46
|
|
47 #ifdef __APPLE__
|
|
48 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
|
|
49 bzero(rwlock, sizeof(pthread_rwlock_t));
|
|
50 #endif
|
|
51
|
|
52 // Initialize the rwlock
|
|
53 int errorcode = pthread_rwlock_init(rwlock, nullptr);
|
|
54 (void)errorcode;
|
|
55 assert(errorcode == 0);
|
|
56
|
|
57 // Assign the data member
|
|
58 data_ = rwlock;
|
|
59 }
|
|
60
|
|
61 // Destruct a RWMutex
|
|
62 RWMutexImpl::~RWMutexImpl()
|
|
63 {
|
|
64 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
|
|
65 assert(rwlock != nullptr);
|
|
66 pthread_rwlock_destroy(rwlock);
|
|
67 free(rwlock);
|
|
68 }
|
|
69
|
|
70 bool
|
|
71 RWMutexImpl::lock_shared()
|
|
72 {
|
|
73 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
|
|
74 assert(rwlock != nullptr);
|
|
75
|
|
76 int errorcode = pthread_rwlock_rdlock(rwlock);
|
|
77 return errorcode == 0;
|
|
78 }
|
|
79
|
|
80 bool
|
|
81 RWMutexImpl::unlock_shared()
|
|
82 {
|
|
83 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
|
|
84 assert(rwlock != nullptr);
|
|
85
|
|
86 int errorcode = pthread_rwlock_unlock(rwlock);
|
|
87 return errorcode == 0;
|
|
88 }
|
|
89
|
|
90 bool
|
|
91 RWMutexImpl::lock()
|
|
92 {
|
|
93 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
|
|
94 assert(rwlock != nullptr);
|
|
95
|
|
96 int errorcode = pthread_rwlock_wrlock(rwlock);
|
|
97 return errorcode == 0;
|
|
98 }
|
|
99
|
|
100 bool
|
|
101 RWMutexImpl::unlock()
|
|
102 {
|
|
103 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
|
|
104 assert(rwlock != nullptr);
|
|
105
|
|
106 int errorcode = pthread_rwlock_unlock(rwlock);
|
|
107 return errorcode == 0;
|
|
108 }
|
|
109
|
|
110 #else
|
|
111
|
|
112 RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { }
|
|
113
|
|
114 RWMutexImpl::~RWMutexImpl() {
|
|
115 delete static_cast<MutexImpl *>(data_);
|
|
116 }
|
|
117
|
|
118 bool RWMutexImpl::lock_shared() {
|
|
119 return static_cast<MutexImpl *>(data_)->acquire();
|
|
120 }
|
|
121
|
|
122 bool RWMutexImpl::unlock_shared() {
|
|
123 return static_cast<MutexImpl *>(data_)->release();
|
|
124 }
|
|
125
|
|
126 bool RWMutexImpl::lock() {
|
|
127 return static_cast<MutexImpl *>(data_)->acquire();
|
|
128 }
|
|
129
|
|
130 bool RWMutexImpl::unlock() {
|
|
131 return static_cast<MutexImpl *>(data_)->release();
|
|
132 }
|
|
133
|
|
134 #endif
|
|
135 #endif
|
|
136 #endif
|