diff options
Diffstat (limited to 'src/RWMutex.hpp')
-rw-r--r-- | src/RWMutex.hpp | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/src/RWMutex.hpp b/src/RWMutex.hpp index 50a78a57b089..a37ac77144f3 100644 --- a/src/RWMutex.hpp +++ b/src/RWMutex.hpp @@ -1,9 +1,8 @@ //===----------------------------- Registers.hpp --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // // Abstract interface to shared reader/writer log, hiding platform and @@ -18,6 +17,9 @@ #include <windows.h> #elif !defined(_LIBUNWIND_HAS_NO_THREADS) #include <pthread.h> +#if defined(__unix__) && defined(__ELF__) && defined(_LIBUNWIND_HAS_COMMENT_LIB_PRAGMA) +#pragma comment(lib, "pthread") +#endif #endif namespace libunwind { @@ -57,11 +59,11 @@ private: SRWLOCK _lock = SRWLOCK_INIT; }; -#else +#elif !defined(LIBUNWIND_USE_WEAK_PTHREAD) class _LIBUNWIND_HIDDEN RWMutex { public: - bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; } + bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; } bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; } bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; } bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; } @@ -70,6 +72,41 @@ private: pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER; }; +#else + +extern "C" int __attribute__((weak)) +pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg); +extern "C" int __attribute__((weak)) +pthread_rwlock_rdlock(pthread_rwlock_t *lock); +extern "C" int __attribute__((weak)) +pthread_rwlock_wrlock(pthread_rwlock_t *lock); +extern "C" int __attribute__((weak)) +pthread_rwlock_unlock(pthread_rwlock_t *lock); + +// Calls to the locking functions are gated on pthread_create, and not the +// functions themselves, because the data structure should only be locked if +// another thread has been created. This is what similar libraries do. + +class _LIBUNWIND_HIDDEN RWMutex { +public: + bool lock_shared() { + return !pthread_create || (pthread_rwlock_rdlock(&_lock) == 0); + } + bool unlock_shared() { + return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0); + } + bool lock() { + return !pthread_create || (pthread_rwlock_wrlock(&_lock) == 0); + } + bool unlock() { + return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0); + } + +private: + pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER; +}; + #endif } // namespace libunwind |