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