summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSterling Augustine <saugustine@google.com>2019-05-13 18:45:03 +0000
committerSterling Augustine <saugustine@google.com>2019-05-13 18:45:03 +0000
commit7981a28d9d303e9e209c16cb2749bc6f47a5b521 (patch)
tree471b30f59a101ee965da6017da28edf12476de42
parent79b2828b3f8fb375a250394c0a70b20064f7e4c6 (diff)
downloadbcm5719-llvm-7981a28d9d303e9e209c16cb2749bc6f47a5b521.tar.gz
bcm5719-llvm-7981a28d9d303e9e209c16cb2749bc6f47a5b521.zip
Add a new LIBUNWIND_WEAK_PTHREAD Cmake option to force
calls into the pthread library use weak symbols. This option allows libpthread to be a weak dependency rather than a hard one. Differential Revision: https://reviews.llvm.org/D60285 llvm-svn: 360610
-rw-r--r--libunwind/CMakeLists.txt1
-rw-r--r--libunwind/src/CMakeLists.txt1
-rw-r--r--libunwind/src/RWMutex.hpp39
3 files changed, 39 insertions, 2 deletions
diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt
index debc8478691..8d48167660f 100644
--- a/libunwind/CMakeLists.txt
+++ b/libunwind/CMakeLists.txt
@@ -134,6 +134,7 @@ option(LIBUNWIND_ENABLE_STATIC "Build libunwind as a static library." ON)
option(LIBUNWIND_ENABLE_CROSS_UNWINDING "Enable cross-platform unwinding support." OFF)
option(LIBUNWIND_ENABLE_ARM_WMMX "Enable unwinding support for ARM WMMX registers." OFF)
option(LIBUNWIND_ENABLE_THREADS "Build libunwind with threading support." ON)
+option(LIBUNWIND_WEAK_PTHREAD_LIB "Use weak references to refer to pthread functions." OFF)
option(LIBUNWIND_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
option(LIBUNWIND_INCLUDE_DOCS "Build the libunwind documentation." ${LLVM_INCLUDE_DOCS})
diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt
index 191f1673f42..9ca773bd662 100644
--- a/libunwind/src/CMakeLists.txt
+++ b/libunwind/src/CMakeLists.txt
@@ -67,6 +67,7 @@ endif()
unwind_append_if(libraries LIBUNWIND_HAS_DL_LIB dl)
if (LIBUNWIND_ENABLE_THREADS)
unwind_append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread)
+ unwind_append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_WEAK_PTHREAD_LIB -DLIBUNWIND_USE_WEAK_PTHREAD=1)
endif()
# Setup flags.
diff --git a/libunwind/src/RWMutex.hpp b/libunwind/src/RWMutex.hpp
index 92c8db3b5d2..7a08bb2af32 100644
--- a/libunwind/src/RWMutex.hpp
+++ b/libunwind/src/RWMutex.hpp
@@ -56,11 +56,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; }
@@ -69,6 +69,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
OpenPOWER on IntegriCloud