blob: c76e6e4a5bd178faf4d4678949dc486b68063315 [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.
Alexandre Ganea8404aeb2020-02-13 22:49:57 -050024 ASSERT_LE(Num.compute_thread_count(),
25 hardware_concurrency().compute_thread_count());
Teresa Johnson2bd812c2016-10-14 00:13:59 +000026}
27
Sam McCalla9c3c172019-10-23 15:34:48 +020028#if LLVM_ENABLE_THREADS
29
30class Notification {
31public:
32 void notify() {
33 {
34 std::lock_guard<std::mutex> Lock(M);
35 Notified = true;
Sam McCall18e6a652020-01-25 15:22:12 +010036 // Broadcast with the lock held, so it's safe to destroy the Notification
37 // after wait() returns.
38 CV.notify_all();
Sam McCalla9c3c172019-10-23 15:34:48 +020039 }
Sam McCalla9c3c172019-10-23 15:34:48 +020040 }
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
51private:
52 bool Notified = false;
53 mutable std::condition_variable CV;
54 mutable std::mutex M;
55};
56
57TEST(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
72TEST(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
Teresa Johnson2bd812c2016-10-14 00:13:59 +000081} // end anon namespace