diff options
Diffstat (limited to 'compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp')
-rw-r--r-- | compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp b/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp new file mode 100644 index 00000000000..c75ef8edb36 --- /dev/null +++ b/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp @@ -0,0 +1,102 @@ +//===-- mutex_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 "mutex.h" + +#include "gtest/gtest.h" + +#include <string.h> + +class TestData { +public: + explicit TestData(scudo::HybridMutex &M) : Mutex(M) { + for (scudo::u32 I = 0; I < Size; I++) + Data[I] = 0; + } + + void write() { + scudo::ScopedLock L(Mutex); + T V0 = Data[0]; + for (scudo::u32 I = 0; I < Size; I++) { + EXPECT_EQ(Data[I], V0); + Data[I]++; + } + } + + void tryWrite() { + if (!Mutex.tryLock()) + return; + T V0 = Data[0]; + for (scudo::u32 I = 0; I < Size; I++) { + EXPECT_EQ(Data[I], V0); + Data[I]++; + } + Mutex.unlock(); + } + + void backoff() { + volatile T LocalData[Size] = {}; + for (scudo::u32 I = 0; I < Size; I++) { + LocalData[I]++; + EXPECT_EQ(LocalData[I], 1U); + } + } + +private: + static const scudo::u32 Size = 64U; + typedef scudo::u64 T; + scudo::HybridMutex &Mutex; + ALIGNED(SCUDO_CACHE_LINE_SIZE) T Data[Size]; +}; + +const scudo::u32 NumberOfThreads = 8; +#if SCUDO_DEBUG +const scudo::u32 NumberOfIterations = 4 * 1024; +#else +const scudo::u32 NumberOfIterations = 16 * 1024; +#endif + +static void *lockThread(void *Param) { + TestData *Data = reinterpret_cast<TestData *>(Param); + for (scudo::u32 I = 0; I < NumberOfIterations; I++) { + Data->write(); + Data->backoff(); + } + return 0; +} + +static void *tryThread(void *Param) { + TestData *Data = reinterpret_cast<TestData *>(Param); + for (scudo::u32 I = 0; I < NumberOfIterations; I++) { + Data->tryWrite(); + Data->backoff(); + } + return 0; +} + +TEST(ScudoMutexTest, Mutex) { + scudo::HybridMutex M; + M.init(); + TestData Data(M); + pthread_t Threads[NumberOfThreads]; + for (scudo::u32 I = 0; I < NumberOfThreads; I++) + pthread_create(&Threads[I], 0, lockThread, &Data); + for (scudo::u32 I = 0; I < NumberOfThreads; I++) + pthread_join(Threads[I], 0); +} + +TEST(ScudoMutexTest, MutexTry) { + scudo::HybridMutex M; + M.init(); + TestData Data(M); + pthread_t Threads[NumberOfThreads]; + for (scudo::u32 I = 0; I < NumberOfThreads; I++) + pthread_create(&Threads[I], 0, tryThread, &Data); + for (scudo::u32 I = 0; I < NumberOfThreads; I++) + pthread_join(Threads[I], 0); +} |