1*ab17ecd1SChiaHungDuan //===-- condition_variable_test.cpp -----------------------------*- C++ -*-===// 2*ab17ecd1SChiaHungDuan // 3*ab17ecd1SChiaHungDuan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*ab17ecd1SChiaHungDuan // See https://llvm.org/LICENSE.txt for license information. 5*ab17ecd1SChiaHungDuan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*ab17ecd1SChiaHungDuan // 7*ab17ecd1SChiaHungDuan //===----------------------------------------------------------------------===// 8*ab17ecd1SChiaHungDuan 9*ab17ecd1SChiaHungDuan #include "tests/scudo_unit_test.h" 10*ab17ecd1SChiaHungDuan 11*ab17ecd1SChiaHungDuan #include "common.h" 12*ab17ecd1SChiaHungDuan #include "condition_variable.h" 13*ab17ecd1SChiaHungDuan #include "mutex.h" 14*ab17ecd1SChiaHungDuan 15*ab17ecd1SChiaHungDuan #include <thread> 16*ab17ecd1SChiaHungDuan simpleWaitAndNotifyAll()17*ab17ecd1SChiaHungDuantemplate <typename ConditionVariableT> void simpleWaitAndNotifyAll() { 18*ab17ecd1SChiaHungDuan constexpr scudo::u32 NumThreads = 2; 19*ab17ecd1SChiaHungDuan constexpr scudo::u32 CounterMax = 1024; 20*ab17ecd1SChiaHungDuan std::thread Threads[NumThreads]; 21*ab17ecd1SChiaHungDuan 22*ab17ecd1SChiaHungDuan scudo::HybridMutex M; 23*ab17ecd1SChiaHungDuan ConditionVariableT CV; 24*ab17ecd1SChiaHungDuan CV.bindTestOnly(M); 25*ab17ecd1SChiaHungDuan scudo::u32 Counter = 0; 26*ab17ecd1SChiaHungDuan 27*ab17ecd1SChiaHungDuan for (scudo::u32 I = 0; I < NumThreads; ++I) { 28*ab17ecd1SChiaHungDuan Threads[I] = std::thread( 29*ab17ecd1SChiaHungDuan [&](scudo::u32 Id) { 30*ab17ecd1SChiaHungDuan do { 31*ab17ecd1SChiaHungDuan scudo::ScopedLock L(M); 32*ab17ecd1SChiaHungDuan if (Counter % NumThreads != Id && Counter < CounterMax) 33*ab17ecd1SChiaHungDuan CV.wait(M); 34*ab17ecd1SChiaHungDuan if (Counter >= CounterMax) { 35*ab17ecd1SChiaHungDuan break; 36*ab17ecd1SChiaHungDuan } else { 37*ab17ecd1SChiaHungDuan ++Counter; 38*ab17ecd1SChiaHungDuan CV.notifyAll(M); 39*ab17ecd1SChiaHungDuan } 40*ab17ecd1SChiaHungDuan } while (true); 41*ab17ecd1SChiaHungDuan }, 42*ab17ecd1SChiaHungDuan I); 43*ab17ecd1SChiaHungDuan } 44*ab17ecd1SChiaHungDuan 45*ab17ecd1SChiaHungDuan for (std::thread &T : Threads) 46*ab17ecd1SChiaHungDuan T.join(); 47*ab17ecd1SChiaHungDuan 48*ab17ecd1SChiaHungDuan EXPECT_EQ(Counter, CounterMax); 49*ab17ecd1SChiaHungDuan } 50*ab17ecd1SChiaHungDuan TEST(ScudoConditionVariableTest,DummyCVWaitAndNotifyAll)51*ab17ecd1SChiaHungDuanTEST(ScudoConditionVariableTest, DummyCVWaitAndNotifyAll) { 52*ab17ecd1SChiaHungDuan simpleWaitAndNotifyAll<scudo::ConditionVariableDummy>(); 53*ab17ecd1SChiaHungDuan } 54*ab17ecd1SChiaHungDuan 55*ab17ecd1SChiaHungDuan #ifdef SCUDO_LINUX TEST(ScudoConditionVariableTest,LinuxCVWaitAndNotifyAll)56*ab17ecd1SChiaHungDuanTEST(ScudoConditionVariableTest, LinuxCVWaitAndNotifyAll) { 57*ab17ecd1SChiaHungDuan simpleWaitAndNotifyAll<scudo::ConditionVariableLinux>(); 58*ab17ecd1SChiaHungDuan } 59*ab17ecd1SChiaHungDuan #endif 60