1*5f757f3fSDimitry Andric //===-- condition_variable_base.h -------------------------------*- C++ -*-===// 2*5f757f3fSDimitry Andric // 3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5f757f3fSDimitry Andric // 7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 8*5f757f3fSDimitry Andric 9*5f757f3fSDimitry Andric #ifndef SCUDO_CONDITION_VARIABLE_BASE_H_ 10*5f757f3fSDimitry Andric #define SCUDO_CONDITION_VARIABLE_BASE_H_ 11*5f757f3fSDimitry Andric 12*5f757f3fSDimitry Andric #include "mutex.h" 13*5f757f3fSDimitry Andric #include "thread_annotations.h" 14*5f757f3fSDimitry Andric 15*5f757f3fSDimitry Andric namespace scudo { 16*5f757f3fSDimitry Andric 17*5f757f3fSDimitry Andric template <typename Derived> class ConditionVariableBase { 18*5f757f3fSDimitry Andric public: 19*5f757f3fSDimitry Andric constexpr ConditionVariableBase() = default; 20*5f757f3fSDimitry Andric 21*5f757f3fSDimitry Andric void bindTestOnly(HybridMutex &Mutex) { 22*5f757f3fSDimitry Andric #if SCUDO_DEBUG 23*5f757f3fSDimitry Andric boundMutex = &Mutex; 24*5f757f3fSDimitry Andric #else 25*5f757f3fSDimitry Andric (void)Mutex; 26*5f757f3fSDimitry Andric #endif 27*5f757f3fSDimitry Andric } 28*5f757f3fSDimitry Andric 29*5f757f3fSDimitry Andric void notifyAll(HybridMutex &M) REQUIRES(M) { 30*5f757f3fSDimitry Andric #if SCUDO_DEBUG 31*5f757f3fSDimitry Andric CHECK_EQ(&M, boundMutex); 32*5f757f3fSDimitry Andric #endif 33*5f757f3fSDimitry Andric getDerived()->notifyAllImpl(M); 34*5f757f3fSDimitry Andric } 35*5f757f3fSDimitry Andric 36*5f757f3fSDimitry Andric void wait(HybridMutex &M) REQUIRES(M) { 37*5f757f3fSDimitry Andric #if SCUDO_DEBUG 38*5f757f3fSDimitry Andric CHECK_EQ(&M, boundMutex); 39*5f757f3fSDimitry Andric #endif 40*5f757f3fSDimitry Andric getDerived()->waitImpl(M); 41*5f757f3fSDimitry Andric } 42*5f757f3fSDimitry Andric 43*5f757f3fSDimitry Andric protected: 44*5f757f3fSDimitry Andric Derived *getDerived() { return static_cast<Derived *>(this); } 45*5f757f3fSDimitry Andric 46*5f757f3fSDimitry Andric #if SCUDO_DEBUG 47*5f757f3fSDimitry Andric // Because thread-safety analysis doesn't support pointer aliasing, we are not 48*5f757f3fSDimitry Andric // able to mark the proper annotations without false positive. Instead, we 49*5f757f3fSDimitry Andric // pass the lock and do the same-lock check separately. 50*5f757f3fSDimitry Andric HybridMutex *boundMutex = nullptr; 51*5f757f3fSDimitry Andric #endif 52*5f757f3fSDimitry Andric }; 53*5f757f3fSDimitry Andric 54*5f757f3fSDimitry Andric } // namespace scudo 55*5f757f3fSDimitry Andric 56*5f757f3fSDimitry Andric #endif // SCUDO_CONDITION_VARIABLE_BASE_H_ 57