mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-12 05:56:28 +00:00
Support: Remove MSVC 2013 workarounds in ThreadPool class.
I have confirmed that these are no longer needed with MSVC 2015. Differential Revision: https://reviews.llvm.org/D34187 llvm-svn: 305347
This commit is contained in:
parent
c0d101cb3c
commit
12a5c419d0
@ -35,17 +35,8 @@ namespace llvm {
|
||||
/// for some work to become available.
|
||||
class ThreadPool {
|
||||
public:
|
||||
#ifndef _MSC_VER
|
||||
using VoidTy = void;
|
||||
using TaskTy = std::function<void()>;
|
||||
using PackagedTaskTy = std::packaged_task<void()>;
|
||||
#else
|
||||
// MSVC 2013 has a bug and can't use std::packaged_task<void()>;
|
||||
// We force it to use bool(bool) instead.
|
||||
using VoidTy = bool;
|
||||
using TaskTy = std::function<bool(bool)>;
|
||||
using PackagedTaskTy = std::packaged_task<bool(bool)>;
|
||||
#endif
|
||||
|
||||
/// Construct a pool with the number of core available on the system (or
|
||||
/// whatever the value returned by std::thread::hardware_concurrency() is).
|
||||
@ -60,30 +51,17 @@ public:
|
||||
/// Asynchronous submission of a task to the pool. The returned future can be
|
||||
/// used to wait for the task to finish and is *non-blocking* on destruction.
|
||||
template <typename Function, typename... Args>
|
||||
inline std::shared_future<VoidTy> async(Function &&F, Args &&... ArgList) {
|
||||
inline std::shared_future<void> async(Function &&F, Args &&... ArgList) {
|
||||
auto Task =
|
||||
std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...);
|
||||
#ifndef _MSC_VER
|
||||
return asyncImpl(std::move(Task));
|
||||
#else
|
||||
// This lambda has to be marked mutable because MSVC 2013's std::bind call
|
||||
// operator isn't const qualified.
|
||||
return asyncImpl([Task](VoidTy) mutable -> VoidTy {
|
||||
Task();
|
||||
return VoidTy();
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Asynchronous submission of a task to the pool. The returned future can be
|
||||
/// used to wait for the task to finish and is *non-blocking* on destruction.
|
||||
template <typename Function>
|
||||
inline std::shared_future<VoidTy> async(Function &&F) {
|
||||
#ifndef _MSC_VER
|
||||
inline std::shared_future<void> async(Function &&F) {
|
||||
return asyncImpl(std::forward<Function>(F));
|
||||
#else
|
||||
return asyncImpl([F] (VoidTy) -> VoidTy { F(); return VoidTy(); });
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Blocking wait for all the threads to complete and the queue to be empty.
|
||||
@ -93,7 +71,7 @@ public:
|
||||
private:
|
||||
/// Asynchronous submission of a task to the pool. The returned future can be
|
||||
/// used to wait for the task to finish and is *non-blocking* on destruction.
|
||||
std::shared_future<VoidTy> asyncImpl(TaskTy F);
|
||||
std::shared_future<void> asyncImpl(TaskTy F);
|
||||
|
||||
/// Threads in flight
|
||||
std::vector<llvm::thread> Threads;
|
||||
|
@ -53,11 +53,7 @@ ThreadPool::ThreadPool(unsigned ThreadCount)
|
||||
Tasks.pop();
|
||||
}
|
||||
// Run the task we just grabbed
|
||||
#ifndef _MSC_VER
|
||||
Task();
|
||||
#else
|
||||
Task(/* unused */ false);
|
||||
#endif
|
||||
|
||||
{
|
||||
// Adjust `ActiveThreads`, in case someone waits on ThreadPool::wait()
|
||||
@ -82,7 +78,7 @@ void ThreadPool::wait() {
|
||||
[&] { return !ActiveThreads && Tasks.empty(); });
|
||||
}
|
||||
|
||||
std::shared_future<ThreadPool::VoidTy> ThreadPool::asyncImpl(TaskTy Task) {
|
||||
std::shared_future<void> ThreadPool::asyncImpl(TaskTy Task) {
|
||||
/// Wrap the Task in a packaged_task to return a future object.
|
||||
PackagedTaskTy PackagedTask(std::move(Task));
|
||||
auto Future = PackagedTask.get_future();
|
||||
@ -128,25 +124,16 @@ void ThreadPool::wait() {
|
||||
while (!Tasks.empty()) {
|
||||
auto Task = std::move(Tasks.front());
|
||||
Tasks.pop();
|
||||
#ifndef _MSC_VER
|
||||
Task();
|
||||
#else
|
||||
Task(/* unused */ false);
|
||||
#endif
|
||||
Task();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_future<ThreadPool::VoidTy> ThreadPool::asyncImpl(TaskTy Task) {
|
||||
#ifndef _MSC_VER
|
||||
std::shared_future<void> ThreadPool::asyncImpl(TaskTy Task) {
|
||||
// Get a Future with launch::deferred execution using std::async
|
||||
auto Future = std::async(std::launch::deferred, std::move(Task)).share();
|
||||
// Wrap the future so that both ThreadPool::wait() can operate and the
|
||||
// returned future can be sync'ed on.
|
||||
PackagedTaskTy PackagedTask([Future]() { Future.get(); });
|
||||
#else
|
||||
auto Future = std::async(std::launch::deferred, std::move(Task), false).share();
|
||||
PackagedTaskTy PackagedTask([Future](bool) -> bool { Future.get(); return false; });
|
||||
#endif
|
||||
Tasks.push(std::move(PackagedTask));
|
||||
return Future;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user