Line data Source code
1 : //===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements the llvm::sys::RWMutex class.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "llvm/Support/Allocator.h"
15 : #include "llvm/Support/RWMutex.h"
16 : #include "llvm/Config/config.h"
17 :
18 : //===----------------------------------------------------------------------===//
19 : //=== WARNING: Implementation here must contain only TRULY operating system
20 : //=== independent code.
21 : //===----------------------------------------------------------------------===//
22 :
23 : #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
24 : // Define all methods as no-ops if threading is explicitly disabled
25 :
26 : using namespace llvm;
27 : using namespace sys;
28 :
29 : RWMutexImpl::RWMutexImpl() = default;
30 : RWMutexImpl::~RWMutexImpl() = default;
31 :
32 : bool RWMutexImpl::reader_acquire() { return true; }
33 : bool RWMutexImpl::reader_release() { return true; }
34 : bool RWMutexImpl::writer_acquire() { return true; }
35 : bool RWMutexImpl::writer_release() { return true; }
36 :
37 : #else
38 :
39 : #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
40 :
41 : #include <cassert>
42 : #include <cstdlib>
43 : #include <pthread.h>
44 :
45 : using namespace llvm;
46 : using namespace sys;
47 :
48 : // Construct a RWMutex using pthread calls
49 113960 : RWMutexImpl::RWMutexImpl()
50 : {
51 : // Declare the pthread_rwlock data structures
52 : pthread_rwlock_t* rwlock =
53 113960 : static_cast<pthread_rwlock_t*>(safe_malloc(sizeof(pthread_rwlock_t)));
54 :
55 : #ifdef __APPLE__
56 : // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
57 : bzero(rwlock, sizeof(pthread_rwlock_t));
58 : #endif
59 :
60 : // Initialize the rwlock
61 113960 : int errorcode = pthread_rwlock_init(rwlock, nullptr);
62 : (void)errorcode;
63 : assert(errorcode == 0);
64 :
65 : // Assign the data member
66 113960 : data_ = rwlock;
67 113960 : }
68 :
69 : // Destruct a RWMutex
70 207558 : RWMutexImpl::~RWMutexImpl()
71 : {
72 103779 : pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
73 : assert(rwlock != nullptr);
74 103779 : pthread_rwlock_destroy(rwlock);
75 103779 : free(rwlock);
76 103779 : }
77 :
78 : bool
79 14896304 : RWMutexImpl::reader_acquire()
80 : {
81 14896304 : pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
82 : assert(rwlock != nullptr);
83 :
84 14896304 : int errorcode = pthread_rwlock_rdlock(rwlock);
85 14896308 : return errorcode == 0;
86 : }
87 :
88 : bool
89 14896298 : RWMutexImpl::reader_release()
90 : {
91 14896298 : pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
92 : assert(rwlock != nullptr);
93 :
94 14896298 : int errorcode = pthread_rwlock_unlock(rwlock);
95 14896308 : return errorcode == 0;
96 : }
97 :
98 : bool
99 24197849 : RWMutexImpl::writer_acquire()
100 : {
101 24197849 : pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
102 : assert(rwlock != nullptr);
103 :
104 24197849 : int errorcode = pthread_rwlock_wrlock(rwlock);
105 24197849 : return errorcode == 0;
106 : }
107 :
108 : bool
109 24197849 : RWMutexImpl::writer_release()
110 : {
111 24197849 : pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
112 : assert(rwlock != nullptr);
113 :
114 24197849 : int errorcode = pthread_rwlock_unlock(rwlock);
115 24197849 : return errorcode == 0;
116 : }
117 :
118 : #elif defined(LLVM_ON_UNIX)
119 : #include "Unix/RWMutex.inc"
120 : #elif defined( _WIN32)
121 : #include "Windows/RWMutex.inc"
122 : #else
123 : #warning Neither LLVM_ON_UNIX nor _WIN32 was set in Support/Mutex.cpp
124 : #endif
125 : #endif
|