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 @@ -155,7 +155,7 @@ #endif //===----------------------------------------------------------------------===// -// GuardBase +// GuardByte //===----------------------------------------------------------------------===// enum class AcquireResult { @@ -170,13 +170,15 @@ static constexpr uint8_t PENDING_BIT = (1 << 1); static constexpr uint8_t WAITING_BIT = (1 << 2); +/// Manages reads and writes to the guard byte. Until cxa_guard_release is +/// called this is basically a wrapper around the Derived class template -struct GuardObject { - GuardObject() = delete; - GuardObject(GuardObject const&) = delete; - GuardObject& operator=(GuardObject const&) = delete; +struct GuardByte { + GuardByte() = delete; + GuardByte(GuardByte const&) = delete; + GuardByte& operator=(GuardByte const&) = delete; - explicit GuardObject(uint8_t* const guard_byte_address) : guard_byte(guard_byte_address) {} + explicit GuardByte(uint8_t* const guard_byte_address) : guard_byte(guard_byte_address) {} public: /// Implements __cxa_guard_acquire @@ -214,7 +216,7 @@ InitByteNoThreads(InitByteNoThreads const&) = delete; InitByteNoThreads& operator=(InitByteNoThreads const&) = delete; - explicit InitByteNoThreads(uint8_t* _init_byte_address) : init_byte_address(_init_byte_address) {} + explicit InitByteNoThreads(uint8_t* _init_byte_address, uint32_t*) : init_byte_address(_init_byte_address) {} /// The init_byte portion of cxa_guard_acquire. /// Note: On completion, we haven't 'acquired' ownership of anything mutex @@ -514,58 +516,49 @@ // Guards //===----------------------------------------------------------------------===// -/// NoThreadsGuard - Manages initialization without performing any inter-thread -/// synchronization. -struct NoThreadsGuard : GuardObject, InitByteNoThreads { - using BaseT = typename NoThreadsGuard::GuardObject; - using InitByteT = typename NoThreadsGuard::InitByteNoThreads; +template +struct GuardBase : GuardByte>, InitByteT { + using GuardByteT = typename GuardBase::GuardByte; + + GuardBase() = delete; + GuardBase(GuardBase const&) = delete; + GuardBase& operator=(GuardBase const&) = delete; + + /// ARM Constructor + explicit GuardBase(uint32_t* raw_guard_object) + : GuardByteT(reinterpret_cast(raw_guard_object)), + InitByteT(reinterpret_cast(raw_guard_object) + 1, nullptr) {} - explicit NoThreadsGuard(uint32_t* raw_guard_object) - : BaseT(reinterpret_cast(raw_guard_object)), - InitByteT(reinterpret_cast(raw_guard_object) + 1) {} + /// Itanium Constructor + explicit GuardBase(uint64_t* raw_guard_object) + : GuardByteT(reinterpret_cast(raw_guard_object)), + InitByteT(reinterpret_cast(raw_guard_object) + 1, reinterpret_cast(raw_guard_object) + 1) { + } +}; - explicit NoThreadsGuard(uint64_t* raw_guard_object) - : BaseT(reinterpret_cast(raw_guard_object)), - InitByteT(reinterpret_cast(raw_guard_object) + 1) {} +/// NoThreadsGuard - Manages initialization without performing any inter-thread +/// synchronization. +struct NoThreadsGuard : GuardBase { + using BaseT = typename NoThreadsGuard::GuardBase; + using BaseT::BaseT; }; /// GlobalMutexGuard - Manages initialization using a global mutex and /// condition variable. template -struct GlobalMutexGuard : GuardObject>, - InitByteGlobalMutex { - - using BaseT = typename GlobalMutexGuard::GuardObject; - using InitByteT = typename GlobalMutexGuard::InitByteGlobalMutex; - - explicit GlobalMutexGuard(uint32_t* raw_guard_object) - : BaseT(reinterpret_cast(raw_guard_object)), - InitByteT(reinterpret_cast(raw_guard_object) + 1, nullptr) {} - explicit GlobalMutexGuard(uint64_t* raw_guard_object) - : BaseT(reinterpret_cast(raw_guard_object)), - InitByteT(reinterpret_cast(raw_guard_object) + 1, reinterpret_cast(raw_guard_object) + 1) { - } +struct GlobalMutexGuard : GuardBase> { + using BaseT = typename GlobalMutexGuard::GuardBase; + using BaseT::BaseT; }; /// FutexGuard - Manages initialization using atomics and the futex syscall for /// waiting and waking. template -struct FutexGuard : GuardObject>, InitByteFutex { - using BaseT = typename FutexGuard::GuardObject; - using InitByteT = typename FutexGuard::InitByteFutex; - - /// ARM Constructor - explicit FutexGuard(uint32_t* raw_guard_object) - : BaseT(reinterpret_cast(raw_guard_object)), - InitByteT(reinterpret_cast(raw_guard_object) + 1, nullptr) {} - - /// Itanium Constructor - explicit FutexGuard(uint64_t* raw_guard_object) - : BaseT(reinterpret_cast(raw_guard_object)), - InitByteT(reinterpret_cast(raw_guard_object) + 1, reinterpret_cast(raw_guard_object) + 1) { - } +struct FutexGuard : GuardBase> { + using BaseT = typename FutexGuard::GuardBase; + using BaseT::BaseT; }; //===----------------------------------------------------------------------===//