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