//===- unittests/Threading.cpp - Thread tests -----------------------------===// // // 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 "llvm/Support/Threading.h" #include "llvm/Support/thread.h" #include "gtest/gtest.h" #include #include using namespace llvm; namespace { TEST(Threading, PhysicalConcurrency) { auto Num = heavyweight_hardware_concurrency(); // Since Num is unsigned this will also catch us trying to // return -1. ASSERT_LE(Num.compute_thread_count(), hardware_concurrency().compute_thread_count()); } #if LLVM_ENABLE_THREADS class Notification { public: void notify() { { std::lock_guard Lock(M); Notified = true; // Broadcast with the lock held, so it's safe to destroy the Notification // after wait() returns. CV.notify_all(); } } bool wait() { std::unique_lock Lock(M); using steady_clock = std::chrono::steady_clock; auto Deadline = steady_clock::now() + std::chrono::duration_cast( std::chrono::duration(5)); return CV.wait_until(Lock, Deadline, [this] { return Notified; }); } private: bool Notified = false; mutable std::condition_variable CV; mutable std::mutex M; }; TEST(Threading, RunOnThreadSyncAsync) { Notification ThreadStarted, ThreadAdvanced, ThreadFinished; auto ThreadFunc = [&] { ThreadStarted.notify(); ASSERT_TRUE(ThreadAdvanced.wait()); ThreadFinished.notify(); }; llvm::llvm_execute_on_thread_async(ThreadFunc); ASSERT_TRUE(ThreadStarted.wait()); ThreadAdvanced.notify(); ASSERT_TRUE(ThreadFinished.wait()); } TEST(Threading, RunOnThreadSync) { std::atomic_bool Executed(false); llvm::llvm_execute_on_thread( [](void *Arg) { *static_cast(Arg) = true; }, &Executed); ASSERT_EQ(Executed, true); } #endif } // end anon namespace