blob: 7a08bb2af32eb37156afdfefa67a3806acfa3b89 [file] [log] [blame]
Martin Storsjo590ffef2017-10-23 19:29:36 +00001//===----------------------------- Registers.hpp --------------------------===//
2//
Chandler Carruth61860a52019-01-19 10:56:40 +00003// 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
Martin Storsjo590ffef2017-10-23 19:29:36 +00006//
7//
8// Abstract interface to shared reader/writer log, hiding platform and
9// configuration differences.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef __RWMUTEX_HPP__
14#define __RWMUTEX_HPP__
15
16#if defined(_WIN32)
17#include <windows.h>
18#elif !defined(_LIBUNWIND_HAS_NO_THREADS)
19#include <pthread.h>
20#endif
21
22namespace libunwind {
23
24#if defined(_LIBUNWIND_HAS_NO_THREADS)
25
26class _LIBUNWIND_HIDDEN RWMutex {
27public:
28 bool lock_shared() { return true; }
29 bool unlock_shared() { return true; }
30 bool lock() { return true; }
31 bool unlock() { return true; }
32};
33
34#elif defined(_WIN32)
35
36class _LIBUNWIND_HIDDEN RWMutex {
37public:
38 bool lock_shared() {
39 AcquireSRWLockShared(&_lock);
40 return true;
41 }
42 bool unlock_shared() {
43 ReleaseSRWLockShared(&_lock);
44 return true;
45 }
46 bool lock() {
47 AcquireSRWLockExclusive(&_lock);
48 return true;
49 }
50 bool unlock() {
51 ReleaseSRWLockExclusive(&_lock);
52 return true;
53 }
54
55private:
56 SRWLOCK _lock = SRWLOCK_INIT;
57};
58
Sterling Augustine7f90e762019-05-13 18:45:03 +000059#elif !defined(LIBUNWIND_USE_WEAK_PTHREAD)
Martin Storsjo590ffef2017-10-23 19:29:36 +000060
61class _LIBUNWIND_HIDDEN RWMutex {
62public:
Sterling Augustine7f90e762019-05-13 18:45:03 +000063 bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; }
Martin Storsjo590ffef2017-10-23 19:29:36 +000064 bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; }
65 bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; }
66 bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; }
67
68private:
69 pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;
70};
71
Sterling Augustine7f90e762019-05-13 18:45:03 +000072#else
73
74extern "C" int __attribute__((weak))
75pthread_create(pthread_t *thread, const pthread_attr_t *attr,
76 void *(*start_routine)(void *), void *arg);
77extern "C" int __attribute__((weak))
78pthread_rwlock_rdlock(pthread_rwlock_t *lock);
79extern "C" int __attribute__((weak))
80pthread_rwlock_wrlock(pthread_rwlock_t *lock);
81extern "C" int __attribute__((weak))
82pthread_rwlock_unlock(pthread_rwlock_t *lock);
83
84// Calls to the locking functions are gated on pthread_create, and not the
85// functions themselves, because the data structure should only be locked if
86// another thread has been created. This is what similar libraries do.
87
88class _LIBUNWIND_HIDDEN RWMutex {
89public:
90 bool lock_shared() {
91 return !pthread_create || (pthread_rwlock_rdlock(&_lock) == 0);
92 }
93 bool unlock_shared() {
94 return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);
95 }
96 bool lock() {
97 return !pthread_create || (pthread_rwlock_wrlock(&_lock) == 0);
98 }
99 bool unlock() {
100 return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);
101 }
102
103private:
104 pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;
105};
106
Martin Storsjo590ffef2017-10-23 19:29:36 +0000107#endif
108
109} // namespace libunwind
110
111#endif // __RWMUTEX_HPP__