82 lines
2.2 KiB
C++
82 lines
2.2 KiB
C++
//===- unittests/Threading.cpp - Thread tests -----------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Support/Threading.h"
|
|
#include "llvm/Support/thread.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
TEST(Threading, PhysicalConcurrency) {
|
|
auto Num = heavyweight_hardware_concurrency();
|
|
// Since Num is unsigned this will also catch us trying to
|
|
// return -1.
|
|
ASSERT_LE(Num.compute_thread_count(),
|
|
hardware_concurrency().compute_thread_count());
|
|
}
|
|
|
|
#if LLVM_ENABLE_THREADS
|
|
|
|
class Notification {
|
|
public:
|
|
void notify() {
|
|
{
|
|
std::lock_guard<std::mutex> Lock(M);
|
|
Notified = true;
|
|
// Broadcast with the lock held, so it's safe to destroy the Notification
|
|
// after wait() returns.
|
|
CV.notify_all();
|
|
}
|
|
}
|
|
|
|
bool wait() {
|
|
std::unique_lock<std::mutex> Lock(M);
|
|
using steady_clock = std::chrono::steady_clock;
|
|
auto Deadline = steady_clock::now() +
|
|
std::chrono::duration_cast<steady_clock::duration>(
|
|
std::chrono::duration<double>(5));
|
|
return CV.wait_until(Lock, Deadline, [this] { return Notified; });
|
|
}
|
|
|
|
private:
|
|
bool Notified = false;
|
|
mutable std::condition_variable CV;
|
|
mutable std::mutex M;
|
|
};
|
|
|
|
TEST(Threading, RunOnThreadSyncAsync) {
|
|
Notification ThreadStarted, ThreadAdvanced, ThreadFinished;
|
|
|
|
auto ThreadFunc = [&] {
|
|
ThreadStarted.notify();
|
|
ASSERT_TRUE(ThreadAdvanced.wait());
|
|
ThreadFinished.notify();
|
|
};
|
|
|
|
llvm::llvm_execute_on_thread_async(ThreadFunc);
|
|
ASSERT_TRUE(ThreadStarted.wait());
|
|
ThreadAdvanced.notify();
|
|
ASSERT_TRUE(ThreadFinished.wait());
|
|
}
|
|
|
|
TEST(Threading, RunOnThreadSync) {
|
|
std::atomic_bool Executed(false);
|
|
llvm::llvm_execute_on_thread(
|
|
[](void *Arg) { *static_cast<std::atomic_bool *>(Arg) = true; },
|
|
&Executed);
|
|
ASSERT_EQ(Executed, true);
|
|
}
|
|
#endif
|
|
|
|
} // end anon namespace
|