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.compute_thread_count(), 25 hardware_concurrency().compute_thread_count()); 26 } 27 28 #if LLVM_ENABLE_THREADS 29 30 class Notification { 31 public: 32 void notify() { 33 { 34 std::lock_guard<std::mutex> Lock(M); 35 Notified = true; 36 // Broadcast with the lock held, so it's safe to destroy the Notification 37 // after wait() returns. 38 CV.notify_all(); 39 } 40 } 41 42 bool wait() { 43 std::unique_lock<std::mutex> Lock(M); 44 using steady_clock = std::chrono::steady_clock; 45 auto Deadline = steady_clock::now() + 46 std::chrono::duration_cast<steady_clock::duration>( 47 std::chrono::duration<double>(5)); 48 return CV.wait_until(Lock, Deadline, [this] { return Notified; }); 49 } 50 51 private: 52 bool Notified = false; 53 mutable std::condition_variable CV; 54 mutable std::mutex M; 55 }; 56 57 TEST(Threading, RunOnThreadSyncAsync) { 58 Notification ThreadStarted, ThreadAdvanced, ThreadFinished; 59 60 auto ThreadFunc = [&] { 61 ThreadStarted.notify(); 62 ASSERT_TRUE(ThreadAdvanced.wait()); 63 ThreadFinished.notify(); 64 }; 65 66 llvm::llvm_execute_on_thread_async(ThreadFunc); 67 ASSERT_TRUE(ThreadStarted.wait()); 68 ThreadAdvanced.notify(); 69 ASSERT_TRUE(ThreadFinished.wait()); 70 } 71 72 TEST(Threading, RunOnThreadSync) { 73 std::atomic_bool Executed(false); 74 llvm::llvm_execute_on_thread( 75 [](void *Arg) { *static_cast<std::atomic_bool *>(Arg) = true; }, 76 &Executed); 77 ASSERT_EQ(Executed, true); 78 } 79 #endif 80 81 } // end anon namespace 82