90 lines · cpp
1//===-- mutex_test.cpp ------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "gwp_asan/mutex.h"10#include "gwp_asan/tests/harness.h"11 12#include <atomic>13#include <mutex>14#include <thread>15#include <vector>16 17using gwp_asan::Mutex;18using gwp_asan::ScopedLock;19 20TEST(GwpAsanMutexTest, LockUnlockTest) {21 Mutex Mu;22 23 ASSERT_TRUE(Mu.tryLock());24 ASSERT_FALSE(Mu.tryLock());25 Mu.unlock();26 27 Mu.lock();28 Mu.unlock();29 30 // Ensure that the mutex actually unlocked.31 ASSERT_TRUE(Mu.tryLock());32 Mu.unlock();33}34 35TEST(GwpAsanMutexTest, ScopedLockUnlockTest) {36 Mutex Mu;37 { ScopedLock L(Mu); }38 // Locking will fail here if the scoped lock failed to unlock.39 EXPECT_TRUE(Mu.tryLock());40 Mu.unlock();41 42 {43 ScopedLock L(Mu);44 EXPECT_FALSE(Mu.tryLock()); // Check that the c'tor did lock.45 46 // Manually unlock and check that this succeeds.47 Mu.unlock();48 EXPECT_TRUE(Mu.tryLock()); // Manually lock.49 }50 EXPECT_TRUE(Mu.tryLock()); // Assert that the scoped destructor did unlock.51 Mu.unlock();52}53 54static void synchronousIncrementTask(std::atomic<bool> *StartingGun, Mutex *Mu,55 unsigned *Counter,56 unsigned NumIterations) {57 while (!StartingGun) {58 // Wait for starting gun.59 }60 for (unsigned i = 0; i < NumIterations; ++i) {61 ScopedLock L(*Mu);62 (*Counter)++;63 }64}65 66static void runSynchronisedTest(unsigned NumThreads, unsigned CounterMax) {67 std::vector<std::thread> Threads;68 69 ASSERT_TRUE(CounterMax % NumThreads == 0);70 71 std::atomic<bool> StartingGun{false};72 Mutex Mu;73 unsigned Counter = 0;74 75 for (unsigned i = 0; i < NumThreads; ++i)76 Threads.emplace_back(synchronousIncrementTask, &StartingGun, &Mu, &Counter,77 CounterMax / NumThreads);78 79 StartingGun = true;80 for (auto &T : Threads)81 T.join();82 83 EXPECT_EQ(CounterMax, Counter);84}85 86TEST(GwpAsanMutexTest, SynchronisedCounterTest) {87 runSynchronisedTest(4, 1000000);88 runSynchronisedTest(100, 1000000);89}90