diff --git a/libcxxabi/src/cxa_guard_impl.h b/libcxxabi/src/cxa_guard_impl.h --- a/libcxxabi/src/cxa_guard_impl.h +++ b/libcxxabi/src/cxa_guard_impl.h @@ -566,6 +566,35 @@ } }; +//===----------------------------------------------------------------------===// +// Convinence Classes +//===----------------------------------------------------------------------===// + +/// NoThreadsGuard - Manages initialization without performing any inter-thread +/// synchronization. +struct NoThreadsGuard : GuardObject<InitByteNoThreads> { + using BaseT = typename NoThreadsGuard::GuardObject; + using BaseT::BaseT; +}; + +/// GlobalMutexGuard - Manages initialization using a global mutex and +/// condition variable. +template <class Mutex, class CondVar, Mutex& global_mutex, CondVar& global_cond, + uint32_t (*GetThreadID)() = PlatformThreadID> +struct GlobalMutexGuard : GuardObject<InitByteGlobalMutex<Mutex, CondVar, global_mutex, global_cond, GetThreadID>> { + using BaseT = typename GlobalMutexGuard::GuardObject; + using BaseT::BaseT; +}; + +/// FutexGuard - Manages initialization using atomics and the futex syscall for +/// waiting and waking. +template <void (*Wait)(int*, int) = PlatformFutexWait, void (*Wake)(int*) = PlatformFutexWake, + uint32_t (*GetThreadIDArg)() = PlatformThreadID> +struct FutexGuard : GuardObject<InitByteFutex<Wait, Wake, GetThreadIDArg>> { + using BaseT = typename FutexGuard::GuardObject; + using BaseT::BaseT; +}; + //===----------------------------------------------------------------------===// // //===----------------------------------------------------------------------===// @@ -582,23 +611,20 @@ template <Implementation Impl> struct SelectImplementation; -/// Manage initialization without performing any inter-thread synchronization. template <> struct SelectImplementation<Implementation::NoThreads> { - using type = GuardObject<InitByteNoThreads>; + using type = NoThreadsGuard; }; -/// Manage initialization using a global mutex and condition variable. template <> struct SelectImplementation<Implementation::GlobalMutex> { - using type = GuardObject<InitByteGlobalMutex<LibcppMutex, LibcppCondVar, GlobalStatic<LibcppMutex>::instance, - GlobalStatic<LibcppCondVar>::instance, PlatformThreadID>>; + using type = GlobalMutexGuard<LibcppMutex, LibcppCondVar, GlobalStatic<LibcppMutex>::instance, + GlobalStatic<LibcppCondVar>::instance, PlatformThreadID>; }; -/// Manage initialization using atomics and the futex syscall for waiting and waking. template <> struct SelectImplementation<Implementation::Futex> { - using type = GuardObject<InitByteFutex<PlatformFutexWait, PlatformFutexWake, PlatformThreadID>>; + using type = FutexGuard<PlatformFutexWait, PlatformFutexWake, PlatformThreadID>; }; // TODO(EricWF): We should prefer the futex implementation when available. But diff --git a/libcxxabi/test/guard_test_basic.pass.cpp b/libcxxabi/test/guard_test_basic.pass.cpp --- a/libcxxabi/test/guard_test_basic.pass.cpp +++ b/libcxxabi/test/guard_test_basic.pass.cpp @@ -119,14 +119,13 @@ { #if defined(_LIBCXXABI_HAS_NO_THREADS) static_assert(CurrentImplementation == Implementation::NoThreads, ""); - static_assert(std::is_same<SelectedImplementation, GuardObject<InitByteNoThreads>>::value, ""); + static_assert(std::is_same<SelectedImplementation, NoThreadsGuard>::value, ""); #else static_assert(CurrentImplementation == Implementation::GlobalMutex, ""); - static_assert( - std::is_same<SelectedImplementation, - GuardObject<InitByteGlobalMutex<LibcppMutex, LibcppCondVar, GlobalStatic<LibcppMutex>::instance, - GlobalStatic<LibcppCondVar>::instance>>>::value, - ""); + static_assert(std::is_same<SelectedImplementation, + GlobalMutexGuard<LibcppMutex, LibcppCondVar, GlobalStatic<LibcppMutex>::instance, + GlobalStatic<LibcppCondVar>::instance>>::value, + ""); #endif } { @@ -139,17 +138,16 @@ } } { - Tests<uint32_t, GuardObject<InitByteNoThreads>>::test(); - Tests<uint64_t, GuardObject<InitByteNoThreads>>::test(); + Tests<uint32_t, NoThreadsGuard>::test(); + Tests<uint64_t, NoThreadsGuard>::test(); } { - using MutexImpl = - GuardObject<InitByteGlobalMutex<NopMutex, NopCondVar, global_nop_mutex, global_nop_cond, MockGetThreadID>>; + using MutexImpl = GlobalMutexGuard<NopMutex, NopCondVar, global_nop_mutex, global_nop_cond, MockGetThreadID>; Tests<uint32_t, MutexImpl>::test(); Tests<uint64_t, MutexImpl>::test(); } { - using FutexImpl = GuardObject<InitByteFutex<&NopFutexWait, &NopFutexWake, &MockGetThreadID>>; + using FutexImpl = FutexGuard<&NopFutexWait, &NopFutexWake, &MockGetThreadID>; Tests<uint32_t, FutexImpl>::test(); Tests<uint64_t, FutexImpl>::test(); }