aboutsummaryrefslogtreecommitdiffstats
path: root/src/RWMutex.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/RWMutex.hpp')
-rw-r--r--src/RWMutex.hpp49
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