forked from OSchip/llvm-project
[libcxxabi] Added convenience classes to cxa_guard
This is the 5th of 5 changes to overhaul cxa_guard. See D108343 for what the final result will be. Depends on D115368 Reviewed By: ldionne, #libc_abi Differential Revision: https://reviews.llvm.org/D115369
This commit is contained in:
parent
29be7c9c4f
commit
f011a53c14
|
@ -589,6 +589,26 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Convenience Classes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// NoThreadsGuard - Manages initialization without performing any inter-thread
|
||||
/// synchronization.
|
||||
using NoThreadsGuard = GuardObject<InitByteNoThreads>;
|
||||
|
||||
/// 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>
|
||||
using GlobalMutexGuard = GuardObject<InitByteGlobalMutex<Mutex, CondVar, global_mutex, global_cond, GetThreadID>>;
|
||||
|
||||
/// 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>
|
||||
using FutexGuard = GuardObject<InitByteFutex<Wait, Wake, GetThreadIDArg>>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -605,23 +625,20 @@ enum class Implementation { NoThreads, GlobalMutex, Futex };
|
|||
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
|
||||
|
|
|
@ -119,14 +119,13 @@ int main(int, char**) {
|
|||
{
|
||||
#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 @@ int main(int, char**) {
|
|||
}
|
||||
}
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue