brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.2 KiB · 3558225 Raw
83 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/LazyAtomicPointer.h"10#include "llvm/Config/llvm-config.h"11#include "llvm/Support/ThreadPool.h"12#include "gtest/gtest.h"13 14using namespace llvm;15 16namespace {17 18TEST(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    });32 33  Threads.wait();34  EXPECT_EQ(Ptr.load(), &Value);35}36 37#if (LLVM_ENABLE_THREADS)38TEST(LazyAtomicPointer, BusyState) {39  int Value = 0;40  LazyAtomicPointer<int> Ptr;41  DefaultThreadPool Threads;42 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.49      {50        std::lock_guard<std::mutex> Lock(BusyLock);51        IsBusy = true;52      }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  });60 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);70 71  // End busy state.72  {73    std::lock_guard<std::mutex> Lock(EndLock);74    IsEnd = true;75  }76  End.notify_all();77  Threads.wait();78  EXPECT_EQ(Ptr.load(), &Value);79}80#endif81 82} // namespace83