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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "mutex.h" 10 11 #include "gtest/gtest.h" 12 13 #include <string.h> 14 15 class TestData { 16 public: 17 explicit TestData(scudo::HybridMutex &M) : Mutex(M) { 18 for (scudo::u32 I = 0; I < Size; I++) 19 Data[I] = 0; 20 } 21 22 void write() { 23 scudo::ScopedLock L(Mutex); 24 T V0 = Data[0]; 25 for (scudo::u32 I = 0; I < Size; I++) { 26 EXPECT_EQ(Data[I], V0); 27 Data[I]++; 28 } 29 } 30 31 void tryWrite() { 32 if (!Mutex.tryLock()) 33 return; 34 T V0 = Data[0]; 35 for (scudo::u32 I = 0; I < Size; I++) { 36 EXPECT_EQ(Data[I], V0); 37 Data[I]++; 38 } 39 Mutex.unlock(); 40 } 41 42 void backoff() { 43 volatile T LocalData[Size] = {}; 44 for (scudo::u32 I = 0; I < Size; I++) { 45 LocalData[I]++; 46 EXPECT_EQ(LocalData[I], 1U); 47 } 48 } 49 50 private: 51 static const scudo::u32 Size = 64U; 52 typedef scudo::u64 T; 53 scudo::HybridMutex &Mutex; 54 ALIGNED(SCUDO_CACHE_LINE_SIZE) T Data[Size]; 55 }; 56 57 const scudo::u32 NumberOfThreads = 8; 58 #if SCUDO_DEBUG 59 const scudo::u32 NumberOfIterations = 4 * 1024; 60 #else 61 const scudo::u32 NumberOfIterations = 16 * 1024; 62 #endif 63 64 static void *lockThread(void *Param) { 65 TestData *Data = reinterpret_cast<TestData *>(Param); 66 for (scudo::u32 I = 0; I < NumberOfIterations; I++) { 67 Data->write(); 68 Data->backoff(); 69 } 70 return 0; 71 } 72 73 static void *tryThread(void *Param) { 74 TestData *Data = reinterpret_cast<TestData *>(Param); 75 for (scudo::u32 I = 0; I < NumberOfIterations; I++) { 76 Data->tryWrite(); 77 Data->backoff(); 78 } 79 return 0; 80 } 81 82 TEST(ScudoMutexTest, Mutex) { 83 scudo::HybridMutex M; 84 M.init(); 85 TestData Data(M); 86 pthread_t Threads[NumberOfThreads]; 87 for (scudo::u32 I = 0; I < NumberOfThreads; I++) 88 pthread_create(&Threads[I], 0, lockThread, &Data); 89 for (scudo::u32 I = 0; I < NumberOfThreads; I++) 90 pthread_join(Threads[I], 0); 91 } 92 93 TEST(ScudoMutexTest, MutexTry) { 94 scudo::HybridMutex M; 95 M.init(); 96 TestData Data(M); 97 pthread_t Threads[NumberOfThreads]; 98 for (scudo::u32 I = 0; I < NumberOfThreads; I++) 99 pthread_create(&Threads[I], 0, tryThread, &Data); 100 for (scudo::u32 I = 0; I < NumberOfThreads; I++) 101 pthread_join(Threads[I], 0); 102 } 103