summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp')
-rw-r--r--compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp102
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);
+}
OpenPOWER on IntegriCloud