115 lines · plain
1//===----------------------------------------------------------------------===//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-exception6//7//8// Abstract interface to shared reader/writer log, hiding platform and9// 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#if defined(__ELF__) && defined(_LIBUNWIND_LINK_PTHREAD_LIB)21#pragma comment(lib, "pthread")22#endif23#endif24 25namespace libunwind {26 27#if defined(_LIBUNWIND_HAS_NO_THREADS)28 29class _LIBUNWIND_HIDDEN RWMutex {30public:31 bool lock_shared() { return true; }32 bool unlock_shared() { return true; }33 bool lock() { return true; }34 bool unlock() { return true; }35};36 37#elif defined(_WIN32)38 39class _LIBUNWIND_HIDDEN RWMutex {40public:41 bool lock_shared() {42 AcquireSRWLockShared(&_lock);43 return true;44 }45 bool unlock_shared() {46 ReleaseSRWLockShared(&_lock);47 return true;48 }49 bool lock() {50 AcquireSRWLockExclusive(&_lock);51 return true;52 }53 bool unlock() {54 ReleaseSRWLockExclusive(&_lock);55 return true;56 }57 58private:59 SRWLOCK _lock = SRWLOCK_INIT;60};61 62#elif !defined(LIBUNWIND_USE_WEAK_PTHREAD)63 64class _LIBUNWIND_HIDDEN RWMutex {65public:66 bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; }67 bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; }68 bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; }69 bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; }70 71private:72 pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;73};74 75#else76 77extern "C" int __attribute__((weak))78pthread_create(pthread_t *thread, const pthread_attr_t *attr,79 void *(*start_routine)(void *), void *arg);80extern "C" int __attribute__((weak))81pthread_rwlock_rdlock(pthread_rwlock_t *lock);82extern "C" int __attribute__((weak))83pthread_rwlock_wrlock(pthread_rwlock_t *lock);84extern "C" int __attribute__((weak))85pthread_rwlock_unlock(pthread_rwlock_t *lock);86 87// Calls to the locking functions are gated on pthread_create, and not the88// functions themselves, because the data structure should only be locked if89// another thread has been created. This is what similar libraries do.90 91class _LIBUNWIND_HIDDEN RWMutex {92public:93 bool lock_shared() {94 return !pthread_create || (pthread_rwlock_rdlock(&_lock) == 0);95 }96 bool unlock_shared() {97 return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);98 }99 bool lock() {100 return !pthread_create || (pthread_rwlock_wrlock(&_lock) == 0);101 }102 bool unlock() {103 return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);104 }105 106private:107 pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;108};109 110#endif111 112} // namespace libunwind113 114#endif // __RWMUTEX_HPP__115