Files
clang-p2996/compiler-rt/lib/gwp_asan/tests/thread_contention.cpp
Mitch Phillips 10939d1d58 [GWP-ASan] Remove thread clamping in tests.
It's better and easier for us to just have threads contend against each
other in the tests if it's more than the maximum supported number of
hardware threads available.

Specifically, the recoverable test fails on Android because the
GTEST_SKIP in a called function, and it only properly works from the
TEST_* harness function. Android tests run on cuttlefish, which can be a
single core with two hyperthreads.

Reviewed By: fmayer

Differential Revision: https://reviews.llvm.org/D143221
2023-02-02 15:40:07 -08:00

66 lines
2.0 KiB
C++

//===-- thread_contention.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 "gwp_asan/tests/harness.h"
// Note: Compilation of <atomic> and <thread> are extremely expensive for
// non-opt builds of clang.
#include <atomic>
#include <cstdlib>
#include <thread>
#include <vector>
void asyncTask(gwp_asan::GuardedPoolAllocator *GPA,
std::atomic<bool> *StartingGun, unsigned NumIterations) {
while (!*StartingGun) {
// Wait for starting gun.
}
// Get ourselves a new allocation.
for (unsigned i = 0; i < NumIterations; ++i) {
volatile char *Ptr = reinterpret_cast<volatile char *>(
GPA->allocate(GPA->getAllocatorState()->maximumAllocationSize()));
// Do any other threads have access to this page?
EXPECT_EQ(*Ptr, 0);
// Mark the page as from malloc. Wait to see if another thread also takes
// this page.
*Ptr = 'A';
std::this_thread::sleep_for(std::chrono::nanoseconds(10000));
// Check we still own the page.
EXPECT_EQ(*Ptr, 'A');
// And now release it.
*Ptr = 0;
GPA->deallocate(const_cast<char *>(Ptr));
}
}
void runThreadContentionTest(unsigned NumThreads, unsigned NumIterations,
gwp_asan::GuardedPoolAllocator *GPA) {
std::atomic<bool> StartingGun{false};
std::vector<std::thread> Threads;
for (unsigned i = 0; i < NumThreads; ++i) {
Threads.emplace_back(asyncTask, GPA, &StartingGun, NumIterations);
}
StartingGun = true;
for (auto &T : Threads)
T.join();
}
TEST_F(CustomGuardedPoolAllocator, ThreadContention) {
unsigned NumThreads = 4;
unsigned NumIterations = 10000;
InitNumSlots(NumThreads);
runThreadContentionTest(NumThreads, NumIterations, &GPA);
}