1 //===- LazyAtomicPointerTest.cpp ------------------------------------------===//
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 "llvm/ADT/LazyAtomicPointer.h"
10 #include "llvm/Config/llvm-config.h"
11 #include "llvm/Support/ThreadPool.h"
12 #include "gtest/gtest.h"
18 TEST(LazyAtomicPointer
, loadOrGenerate
) {
20 LazyAtomicPointer
<int> Ptr
;
21 DefaultThreadPool Threads
;
22 for (unsigned I
= 0; I
< 4; ++I
)
24 Ptr
.loadOrGenerate([&]() {
25 // Make sure this is only called once.
26 static std::atomic
<bool> Once(false);
28 EXPECT_TRUE(Once
.compare_exchange_strong(Current
, true));
34 EXPECT_EQ(Ptr
.load(), &Value
);
37 #if (LLVM_ENABLE_THREADS)
38 TEST(LazyAtomicPointer
, BusyState
) {
40 LazyAtomicPointer
<int> Ptr
;
41 DefaultThreadPool Threads
;
43 std::mutex BusyLock
, EndLock
;
44 std::condition_variable Busy
, End
;
45 bool IsBusy
= false, IsEnd
= false;
47 Ptr
.loadOrGenerate([&]() {
50 std::lock_guard
<std::mutex
> Lock(BusyLock
);
54 std::unique_lock
<std::mutex
> LEnd(EndLock
);
55 // Wait for end state.
56 End
.wait(LEnd
, [&]() { return IsEnd
; });
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);
73 std::lock_guard
<std::mutex
> Lock(EndLock
);
78 EXPECT_EQ(Ptr
.load(), &Value
);