| //===-- condition_variable_test.cpp -----------------------------*- C++ -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "tests/scudo_unit_test.h" | |
| #include "common.h" | |
| #include "condition_variable.h" | |
| #include "mutex.h" | |
| #include <thread> | |
| template <typename ConditionVariableT> void simpleWaitAndNotifyAll() { | |
| constexpr scudo::u32 NumThreads = 2; | |
| constexpr scudo::u32 CounterMax = 1024; | |
| std::thread Threads[NumThreads]; | |
| scudo::HybridMutex M; | |
| ConditionVariableT CV; | |
| CV.bindTestOnly(M); | |
| scudo::u32 Counter = 0; | |
| for (scudo::u32 I = 0; I < NumThreads; ++I) { | |
| Threads[I] = std::thread( | |
| [&](scudo::u32 Id) { | |
| do { | |
| scudo::ScopedLock L(M); | |
| if (Counter % NumThreads != Id && Counter < CounterMax) | |
| CV.wait(M); | |
| if (Counter >= CounterMax) { | |
| break; | |
| } else { | |
| ++Counter; | |
| CV.notifyAll(M); | |
| } | |
| } while (true); | |
| }, | |
| I); | |
| } | |
| for (std::thread &T : Threads) | |
| T.join(); | |
| EXPECT_EQ(Counter, CounterMax); | |
| } | |
| TEST(ScudoConditionVariableTest, DummyCVWaitAndNotifyAll) { | |
| simpleWaitAndNotifyAll<scudo::ConditionVariableDummy>(); | |
| } | |
| #ifdef SCUDO_LINUX | |
| TEST(ScudoConditionVariableTest, LinuxCVWaitAndNotifyAll) { | |
| simpleWaitAndNotifyAll<scudo::ConditionVariableLinux>(); | |
| } | |
| #endif |