forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			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
 |