[gcov] Bump default version to 11.1
[llvm-project.git] / llvm / unittests / ADT / LazyAtomicPointerTest.cpp
blob355822565426848c38fe39c7c204b2823e6e42b2
1 //===- LazyAtomicPointerTest.cpp ------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/LazyAtomicPointer.h"
10 #include "llvm/Config/llvm-config.h"
11 #include "llvm/Support/ThreadPool.h"
12 #include "gtest/gtest.h"
14 using namespace llvm;
16 namespace {
18 TEST(LazyAtomicPointer, loadOrGenerate) {
19 int Value = 0;
20 LazyAtomicPointer<int> Ptr;
21 DefaultThreadPool Threads;
22 for (unsigned I = 0; I < 4; ++I)
23 Threads.async([&]() {
24 Ptr.loadOrGenerate([&]() {
25 // Make sure this is only called once.
26 static std::atomic<bool> Once(false);
27 bool Current = false;
28 EXPECT_TRUE(Once.compare_exchange_strong(Current, true));
29 return &Value;
30 });
31 });
33 Threads.wait();
34 EXPECT_EQ(Ptr.load(), &Value);
37 #if (LLVM_ENABLE_THREADS)
38 TEST(LazyAtomicPointer, BusyState) {
39 int Value = 0;
40 LazyAtomicPointer<int> Ptr;
41 DefaultThreadPool Threads;
43 std::mutex BusyLock, EndLock;
44 std::condition_variable Busy, End;
45 bool IsBusy = false, IsEnd = false;
46 Threads.async([&]() {
47 Ptr.loadOrGenerate([&]() {
48 // Notify busy state.
50 std::lock_guard<std::mutex> Lock(BusyLock);
51 IsBusy = true;
53 Busy.notify_all();
54 std::unique_lock<std::mutex> LEnd(EndLock);
55 // Wait for end state.
56 End.wait(LEnd, [&]() { return IsEnd; });
57 return &Value;
58 });
59 });
61 // Wait for busy state.
62 std::unique_lock<std::mutex> LBusy(BusyLock);
63 Busy.wait(LBusy, [&]() { return IsBusy; });
64 int *ExistingValue = nullptr;
65 // Busy state will not exchange the value.
66 EXPECT_FALSE(Ptr.compare_exchange_weak(ExistingValue, nullptr));
67 // Busy state return nullptr on load/compare_exchange_weak.
68 EXPECT_EQ(ExistingValue, nullptr);
69 EXPECT_EQ(Ptr.load(), nullptr);
71 // End busy state.
73 std::lock_guard<std::mutex> Lock(EndLock);
74 IsEnd = true;
76 End.notify_all();
77 Threads.wait();
78 EXPECT_EQ(Ptr.load(), &Value);
80 #endif
82 } // namespace