xref: /freebsd/contrib/llvm-project/libunwind/src/RWMutex.hpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===----------------------------- Registers.hpp --------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //
8*0b57cec5SDimitry Andric // Abstract interface to shared reader/writer log, hiding platform and
9*0b57cec5SDimitry Andric // configuration differences.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #ifndef __RWMUTEX_HPP__
14*0b57cec5SDimitry Andric #define __RWMUTEX_HPP__
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #if defined(_WIN32)
17*0b57cec5SDimitry Andric #include <windows.h>
18*0b57cec5SDimitry Andric #elif !defined(_LIBUNWIND_HAS_NO_THREADS)
19*0b57cec5SDimitry Andric #include <pthread.h>
20*0b57cec5SDimitry Andric #if defined(__unix__) &&  defined(__ELF__) && defined(_LIBUNWIND_HAS_COMMENT_LIB_PRAGMA)
21*0b57cec5SDimitry Andric #pragma comment(lib, "pthread")
22*0b57cec5SDimitry Andric #endif
23*0b57cec5SDimitry Andric #endif
24*0b57cec5SDimitry Andric 
25*0b57cec5SDimitry Andric namespace libunwind {
26*0b57cec5SDimitry Andric 
27*0b57cec5SDimitry Andric #if defined(_LIBUNWIND_HAS_NO_THREADS)
28*0b57cec5SDimitry Andric 
29*0b57cec5SDimitry Andric class _LIBUNWIND_HIDDEN RWMutex {
30*0b57cec5SDimitry Andric public:
31*0b57cec5SDimitry Andric   bool lock_shared() { return true; }
32*0b57cec5SDimitry Andric   bool unlock_shared() { return true; }
33*0b57cec5SDimitry Andric   bool lock() { return true; }
34*0b57cec5SDimitry Andric   bool unlock() { return true; }
35*0b57cec5SDimitry Andric };
36*0b57cec5SDimitry Andric 
37*0b57cec5SDimitry Andric #elif defined(_WIN32)
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric class _LIBUNWIND_HIDDEN RWMutex {
40*0b57cec5SDimitry Andric public:
41*0b57cec5SDimitry Andric   bool lock_shared() {
42*0b57cec5SDimitry Andric     AcquireSRWLockShared(&_lock);
43*0b57cec5SDimitry Andric     return true;
44*0b57cec5SDimitry Andric   }
45*0b57cec5SDimitry Andric   bool unlock_shared() {
46*0b57cec5SDimitry Andric     ReleaseSRWLockShared(&_lock);
47*0b57cec5SDimitry Andric     return true;
48*0b57cec5SDimitry Andric   }
49*0b57cec5SDimitry Andric   bool lock() {
50*0b57cec5SDimitry Andric     AcquireSRWLockExclusive(&_lock);
51*0b57cec5SDimitry Andric     return true;
52*0b57cec5SDimitry Andric   }
53*0b57cec5SDimitry Andric   bool unlock() {
54*0b57cec5SDimitry Andric     ReleaseSRWLockExclusive(&_lock);
55*0b57cec5SDimitry Andric     return true;
56*0b57cec5SDimitry Andric   }
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric private:
59*0b57cec5SDimitry Andric   SRWLOCK _lock = SRWLOCK_INIT;
60*0b57cec5SDimitry Andric };
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric #elif !defined(LIBUNWIND_USE_WEAK_PTHREAD)
63*0b57cec5SDimitry Andric 
64*0b57cec5SDimitry Andric class _LIBUNWIND_HIDDEN RWMutex {
65*0b57cec5SDimitry Andric public:
66*0b57cec5SDimitry Andric   bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0;  }
67*0b57cec5SDimitry Andric   bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; }
68*0b57cec5SDimitry Andric   bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; }
69*0b57cec5SDimitry Andric   bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; }
70*0b57cec5SDimitry Andric 
71*0b57cec5SDimitry Andric private:
72*0b57cec5SDimitry Andric   pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;
73*0b57cec5SDimitry Andric };
74*0b57cec5SDimitry Andric 
75*0b57cec5SDimitry Andric #else
76*0b57cec5SDimitry Andric 
77*0b57cec5SDimitry Andric extern "C" int __attribute__((weak))
78*0b57cec5SDimitry Andric pthread_create(pthread_t *thread, const pthread_attr_t *attr,
79*0b57cec5SDimitry Andric                void *(*start_routine)(void *), void *arg);
80*0b57cec5SDimitry Andric extern "C" int __attribute__((weak))
81*0b57cec5SDimitry Andric pthread_rwlock_rdlock(pthread_rwlock_t *lock);
82*0b57cec5SDimitry Andric extern "C" int __attribute__((weak))
83*0b57cec5SDimitry Andric pthread_rwlock_wrlock(pthread_rwlock_t *lock);
84*0b57cec5SDimitry Andric extern "C" int __attribute__((weak))
85*0b57cec5SDimitry Andric pthread_rwlock_unlock(pthread_rwlock_t *lock);
86*0b57cec5SDimitry Andric 
87*0b57cec5SDimitry Andric // Calls to the locking functions are gated on pthread_create, and not the
88*0b57cec5SDimitry Andric // functions themselves, because the data structure should only be locked if
89*0b57cec5SDimitry Andric // another thread has been created. This is what similar libraries do.
90*0b57cec5SDimitry Andric 
91*0b57cec5SDimitry Andric class _LIBUNWIND_HIDDEN RWMutex {
92*0b57cec5SDimitry Andric public:
93*0b57cec5SDimitry Andric   bool lock_shared() {
94*0b57cec5SDimitry Andric     return !pthread_create || (pthread_rwlock_rdlock(&_lock) == 0);
95*0b57cec5SDimitry Andric   }
96*0b57cec5SDimitry Andric   bool unlock_shared() {
97*0b57cec5SDimitry Andric     return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);
98*0b57cec5SDimitry Andric   }
99*0b57cec5SDimitry Andric   bool lock() {
100*0b57cec5SDimitry Andric     return !pthread_create || (pthread_rwlock_wrlock(&_lock) == 0);
101*0b57cec5SDimitry Andric   }
102*0b57cec5SDimitry Andric   bool unlock() {
103*0b57cec5SDimitry Andric     return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);
104*0b57cec5SDimitry Andric   }
105*0b57cec5SDimitry Andric 
106*0b57cec5SDimitry Andric private:
107*0b57cec5SDimitry Andric   pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;
108*0b57cec5SDimitry Andric };
109*0b57cec5SDimitry Andric 
110*0b57cec5SDimitry Andric #endif
111*0b57cec5SDimitry Andric 
112*0b57cec5SDimitry Andric } // namespace libunwind
113*0b57cec5SDimitry Andric 
114*0b57cec5SDimitry Andric #endif // __RWMUTEX_HPP__
115