1 //===- unittests/Threading.cpp - Thread tests -----------------------------===// 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 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Support/Threading.h" 10 #include "llvm/Support/thread.h" 11 #include "gtest/gtest.h" 12 13 #include <atomic> 14 #include <condition_variable> 15 16 using namespace llvm; 17 18 namespace { 19 20 TEST(Threading, PhysicalConcurrency) { 21 auto Num = heavyweight_hardware_concurrency(); 22 // Since Num is unsigned this will also catch us trying to 23 // return -1. 24 ASSERT_LE(Num, thread::hardware_concurrency()); 25 } 26 27 #if LLVM_ENABLE_THREADS 28 29 class Notification { 30 public: 31 void notify() { 32 { 33 std::lock_guard<std::mutex> Lock(M); 34 Notified = true; 35 } 36 CV.notify_all(); 37 } 38 39 bool wait() { 40 std::unique_lock<std::mutex> Lock(M); 41 using steady_clock = std::chrono::steady_clock; 42 auto Deadline = steady_clock::now() + 43 std::chrono::duration_cast<steady_clock::duration>( 44 std::chrono::duration<double>(5)); 45 return CV.wait_until(Lock, Deadline, [this] { return Notified; }); 46 } 47 48 private: 49 bool Notified = false; 50 mutable std::condition_variable CV; 51 mutable std::mutex M; 52 }; 53 54 TEST(Threading, RunOnThreadSyncAsync) { 55 Notification ThreadStarted, ThreadAdvanced, ThreadFinished; 56 57 auto ThreadFunc = [&] { 58 ThreadStarted.notify(); 59 ASSERT_TRUE(ThreadAdvanced.wait()); 60 ThreadFinished.notify(); 61 }; 62 63 llvm::llvm_execute_on_thread_async(ThreadFunc); 64 ASSERT_TRUE(ThreadStarted.wait()); 65 ThreadAdvanced.notify(); 66 ASSERT_TRUE(ThreadFinished.wait()); 67 } 68 69 TEST(Threading, RunOnThreadSync) { 70 std::atomic_bool Executed(false); 71 llvm::llvm_execute_on_thread( 72 [](void *Arg) { *static_cast<std::atomic_bool *>(Arg) = true; }, 73 &Executed); 74 ASSERT_EQ(Executed, true); 75 } 76 #endif 77 78 } // end anon namespace 79