1 //===-- thread_contention.cpp -----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "gwp_asan/tests/harness.h"
11 // Note: Compilation of <atomic> and <thread> are extremely expensive for
12 // non-opt builds of clang.
18 void asyncTask(gwp_asan::GuardedPoolAllocator
*GPA
,
19 std::atomic
<bool> *StartingGun
, unsigned NumIterations
) {
20 while (!*StartingGun
) {
21 // Wait for starting gun.
24 // Get ourselves a new allocation.
25 for (unsigned i
= 0; i
< NumIterations
; ++i
) {
26 volatile char *Ptr
= reinterpret_cast<volatile char *>(
27 GPA
->allocate(GPA
->getAllocatorState()->maximumAllocationSize()));
28 // Do any other threads have access to this page?
31 // Mark the page as from malloc. Wait to see if another thread also takes
34 std::this_thread::sleep_for(std::chrono::nanoseconds(10000));
36 // Check we still own the page.
39 // And now release it.
41 GPA
->deallocate(const_cast<char *>(Ptr
));
45 void runThreadContentionTest(unsigned NumThreads
, unsigned NumIterations
,
46 gwp_asan::GuardedPoolAllocator
*GPA
) {
47 std::atomic
<bool> StartingGun
{false};
48 std::vector
<std::thread
> Threads
;
50 for (unsigned i
= 0; i
< NumThreads
; ++i
) {
51 Threads
.emplace_back(asyncTask
, GPA
, &StartingGun
, NumIterations
);
56 for (auto &T
: Threads
)
60 TEST_F(CustomGuardedPoolAllocator
, ThreadContention
) {
61 unsigned NumThreads
= 4;
62 unsigned NumIterations
= 10000;
63 InitNumSlots(NumThreads
);
64 runThreadContentionTest(NumThreads
, NumIterations
, &GPA
);