blob: 183c9aa7d71c4170bb4a0a03594daaf5dbd6b2fb [file] [log] [blame]
Teresa Johnson2bd812c2016-10-14 00:13:59 +00001//===- unittests/Threading.cpp - Thread tests -----------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Teresa Johnson2bd812c2016-10-14 00:13:59 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/Support/Threading.h"
10#include "llvm/Support/thread.h"
11#include "gtest/gtest.h"
12
Sam McCalla9c3c172019-10-23 15:34:48 +020013#include <atomic>
14#include <condition_variable>
15
Teresa Johnson2bd812c2016-10-14 00:13:59 +000016using namespace llvm;
17
18namespace {
19
20TEST(Threading, PhysicalConcurrency) {
Teresa Johnsonc0ef9e42016-10-17 14:56:53 +000021 auto Num = heavyweight_hardware_concurrency();
Teresa Johnson2bd812c2016-10-14 00:13:59 +000022 // Since Num is unsigned this will also catch us trying to
23 // return -1.
24 ASSERT_LE(Num, thread::hardware_concurrency());
25}
26
Sam McCalla9c3c172019-10-23 15:34:48 +020027#if LLVM_ENABLE_THREADS
28
29class Notification {
30public:
31 void notify() {
32 {
33 std::lock_guard<std::mutex> Lock(M);
34 Notified = true;
Sam McCall18e6a652020-01-25 15:22:12 +010035 // Broadcast with the lock held, so it's safe to destroy the Notification
36 // after wait() returns.
37 CV.notify_all();
Sam McCalla9c3c172019-10-23 15:34:48 +020038 }
Sam McCalla9c3c172019-10-23 15:34:48 +020039 }
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
50private:
51 bool Notified = false;
52 mutable std::condition_variable CV;
53 mutable std::mutex M;
54};
55
56TEST(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
71TEST(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
Teresa Johnson2bd812c2016-10-14 00:13:59 +000080} // end anon namespace