summaryrefslogtreecommitdiffstats
path: root/lib/libcxxabi/src/cxa_guard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libcxxabi/src/cxa_guard.cpp')
-rw-r--r--lib/libcxxabi/src/cxa_guard.cpp265
1 files changed, 0 insertions, 265 deletions
diff --git a/lib/libcxxabi/src/cxa_guard.cpp b/lib/libcxxabi/src/cxa_guard.cpp
deleted file mode 100644
index f4c2a184dc5..00000000000
--- a/lib/libcxxabi/src/cxa_guard.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-//===---------------------------- cxa_guard.cpp ---------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-#include "__cxxabi_config.h"
-
-#include "abort_message.h"
-#include <__threading_support>
-
-#include <stdint.h>
-
-/*
- This implementation must be careful to not call code external to this file
- which will turn around and try to call __cxa_guard_acquire reentrantly.
- For this reason, the headers of this file are as restricted as possible.
- Previous implementations of this code for __APPLE__ have used
- std::__libcpp_mutex_lock and the abort_message utility without problem. This
- implementation also uses std::__libcpp_condvar_wait which has tested
- to not be a problem.
-*/
-
-namespace __cxxabiv1
-{
-
-namespace
-{
-
-#ifdef __arm__
-// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must
-// be statically initialized to 0.
-typedef uint32_t guard_type;
-
-inline void set_initialized(guard_type* guard_object) {
- *guard_object |= 1;
-}
-#else
-typedef uint64_t guard_type;
-
-void set_initialized(guard_type* guard_object) {
- char* initialized = (char*)guard_object;
- *initialized = 1;
-}
-#endif
-
-#if defined(_LIBCXXABI_HAS_NO_THREADS) || (defined(__APPLE__) && !defined(__arm__))
-#ifdef __arm__
-
-// Test the lowest bit.
-inline bool is_initialized(guard_type* guard_object) {
- return (*guard_object) & 1;
-}
-
-#else
-
-bool is_initialized(guard_type* guard_object) {
- char* initialized = (char*)guard_object;
- return *initialized;
-}
-
-#endif
-#endif
-
-#ifndef _LIBCXXABI_HAS_NO_THREADS
-std::__libcpp_mutex_t guard_mut = _LIBCPP_MUTEX_INITIALIZER;
-std::__libcpp_condvar_t guard_cv = _LIBCPP_CONDVAR_INITIALIZER;
-#endif
-
-#if defined(__APPLE__) && !defined(__arm__)
-
-typedef uint32_t lock_type;
-
-#if __LITTLE_ENDIAN__
-
-inline
-lock_type
-get_lock(uint64_t x)
-{
- return static_cast<lock_type>(x >> 32);
-}
-
-inline
-void
-set_lock(uint64_t& x, lock_type y)
-{
- x = static_cast<uint64_t>(y) << 32;
-}
-
-#else // __LITTLE_ENDIAN__
-
-inline
-lock_type
-get_lock(uint64_t x)
-{
- return static_cast<lock_type>(x);
-}
-
-inline
-void
-set_lock(uint64_t& x, lock_type y)
-{
- x = y;
-}
-
-#endif // __LITTLE_ENDIAN__
-
-#else // !__APPLE__ || __arm__
-
-typedef bool lock_type;
-
-#if !defined(__arm__)
-static_assert(std::is_same<guard_type, uint64_t>::value, "");
-
-inline lock_type get_lock(uint64_t x)
-{
- union
- {
- uint64_t guard;
- uint8_t lock[2];
- } f = {x};
- return f.lock[1] != 0;
-}
-
-inline void set_lock(uint64_t& x, lock_type y)
-{
- union
- {
- uint64_t guard;
- uint8_t lock[2];
- } f = {0};
- f.lock[1] = y;
- x = f.guard;
-}
-#else // defined(__arm__)
-static_assert(std::is_same<guard_type, uint32_t>::value, "");
-
-inline lock_type get_lock(uint32_t x)
-{
- union
- {
- uint32_t guard;
- uint8_t lock[2];
- } f = {x};
- return f.lock[1] != 0;
-}
-
-inline void set_lock(uint32_t& x, lock_type y)
-{
- union
- {
- uint32_t guard;
- uint8_t lock[2];
- } f = {0};
- f.lock[1] = y;
- x = f.guard;
-}
-
-#endif // !defined(__arm__)
-
-#endif // __APPLE__ && !__arm__
-
-} // unnamed namespace
-
-extern "C"
-{
-
-#ifndef _LIBCXXABI_HAS_NO_THREADS
-_LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) {
- char* initialized = (char*)guard_object;
- if (std::__libcpp_mutex_lock(&guard_mut))
- abort_message("__cxa_guard_acquire failed to acquire mutex");
- int result = *initialized == 0;
- if (result)
- {
-#if defined(__APPLE__) && !defined(__arm__)
- // This is a special-case pthread dependency for Mac. We can't pull this
- // out into libcxx's threading API (__threading_support) because not all
- // supported Mac environments provide this function (in pthread.h). To
- // make it possible to build/use libcxx in those environments, we have to
- // keep this pthread dependency local to libcxxabi. If there is some
- // convenient way to detect precisely when pthread_mach_thread_np is
- // available in a given Mac environment, it might still be possible to
- // bury this dependency in __threading_support.
- #ifdef _LIBCPP_HAS_THREAD_API_PTHREAD
- const lock_type id = pthread_mach_thread_np(std::__libcpp_thread_get_current_id());
- #else
- #error "How do I pthread_mach_thread_np()?"
- #endif
- lock_type lock = get_lock(*guard_object);
- if (lock)
- {
- // if this thread set lock for this same guard_object, abort
- if (lock == id)
- abort_message("__cxa_guard_acquire detected deadlock");
- do
- {
- if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut))
- abort_message("__cxa_guard_acquire condition variable wait failed");
- lock = get_lock(*guard_object);
- } while (lock);
- result = !is_initialized(guard_object);
- if (result)
- set_lock(*guard_object, id);
- }
- else
- set_lock(*guard_object, id);
-#else // !__APPLE__ || __arm__
- while (get_lock(*guard_object))
- if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut))
- abort_message("__cxa_guard_acquire condition variable wait failed");
- result = *initialized == 0;
- if (result)
- set_lock(*guard_object, true);
-#endif // !__APPLE__ || __arm__
- }
- if (std::__libcpp_mutex_unlock(&guard_mut))
- abort_message("__cxa_guard_acquire failed to release mutex");
- return result;
-}
-
-_LIBCXXABI_FUNC_VIS void __cxa_guard_release(guard_type *guard_object) {
- if (std::__libcpp_mutex_lock(&guard_mut))
- abort_message("__cxa_guard_release failed to acquire mutex");
- *guard_object = 0;
- set_initialized(guard_object);
- if (std::__libcpp_mutex_unlock(&guard_mut))
- abort_message("__cxa_guard_release failed to release mutex");
- if (std::__libcpp_condvar_broadcast(&guard_cv))
- abort_message("__cxa_guard_release failed to broadcast condition variable");
-}
-
-_LIBCXXABI_FUNC_VIS void __cxa_guard_abort(guard_type *guard_object) {
- if (std::__libcpp_mutex_lock(&guard_mut))
- abort_message("__cxa_guard_abort failed to acquire mutex");
- *guard_object = 0;
- if (std::__libcpp_mutex_unlock(&guard_mut))
- abort_message("__cxa_guard_abort failed to release mutex");
- if (std::__libcpp_condvar_broadcast(&guard_cv))
- abort_message("__cxa_guard_abort failed to broadcast condition variable");
-}
-
-#else // _LIBCXXABI_HAS_NO_THREADS
-
-_LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) {
- return !is_initialized(guard_object);
-}
-
-_LIBCXXABI_FUNC_VIS void __cxa_guard_release(guard_type *guard_object) {
- *guard_object = 0;
- set_initialized(guard_object);
-}
-
-_LIBCXXABI_FUNC_VIS void __cxa_guard_abort(guard_type *guard_object) {
- *guard_object = 0;
-}
-
-#endif // !_LIBCXXABI_HAS_NO_THREADS
-
-} // extern "C"
-
-} // __cxxabiv1