ThreadPool.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. //===-- llvm/Support/ThreadPool.h - A ThreadPool implementation -*- C++ -*-===//
  2. //
  3. // 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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines a crude C++11 based thread pool.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_SUPPORT_THREADPOOL_H
  13. #define LLVM_SUPPORT_THREADPOOL_H
  14. #include "llvm/Config/llvm-config.h"
  15. #include "llvm/Support/Threading.h"
  16. #include "llvm/Support/thread.h"
  17. #include <future>
  18. #include <atomic>
  19. #include <condition_variable>
  20. #include <functional>
  21. #include <memory>
  22. #include <mutex>
  23. #include <queue>
  24. #include <utility>
  25. namespace llvm {
  26. /// A ThreadPool for asynchronous parallel execution on a defined number of
  27. /// threads.
  28. ///
  29. /// The pool keeps a vector of threads alive, waiting on a condition variable
  30. /// for some work to become available.
  31. class ThreadPool {
  32. public:
  33. using TaskTy = std::function<void()>;
  34. using PackagedTaskTy = std::packaged_task<void()>;
  35. /// Construct a pool using the hardware strategy \p S for mapping hardware
  36. /// execution resources (threads, cores, CPUs)
  37. /// Defaults to using the maximum execution resources in the system, but
  38. /// accounting for the affinity mask.
  39. ThreadPool(ThreadPoolStrategy S = hardware_concurrency());
  40. /// Blocking destructor: the pool will wait for all the threads to complete.
  41. ~ThreadPool();
  42. /// Asynchronous submission of a task to the pool. The returned future can be
  43. /// used to wait for the task to finish and is *non-blocking* on destruction.
  44. template <typename Function, typename... Args>
  45. inline std::shared_future<void> async(Function &&F, Args &&... ArgList) {
  46. auto Task =
  47. std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...);
  48. return asyncImpl(std::move(Task));
  49. }
  50. /// Asynchronous submission of a task to the pool. The returned future can be
  51. /// used to wait for the task to finish and is *non-blocking* on destruction.
  52. template <typename Function>
  53. inline std::shared_future<void> async(Function &&F) {
  54. return asyncImpl(std::forward<Function>(F));
  55. }
  56. /// Blocking wait for all the threads to complete and the queue to be empty.
  57. /// It is an error to try to add new tasks while blocking on this call.
  58. void wait();
  59. unsigned getThreadCount() const { return ThreadCount; }
  60. private:
  61. bool workCompletedUnlocked() { return !ActiveThreads && Tasks.empty(); }
  62. /// Asynchronous submission of a task to the pool. The returned future can be
  63. /// used to wait for the task to finish and is *non-blocking* on destruction.
  64. std::shared_future<void> asyncImpl(TaskTy F);
  65. /// Threads in flight
  66. std::vector<llvm::thread> Threads;
  67. /// Tasks waiting for execution in the pool.
  68. std::queue<PackagedTaskTy> Tasks;
  69. /// Locking and signaling for accessing the Tasks queue.
  70. std::mutex QueueLock;
  71. std::condition_variable QueueCondition;
  72. /// Signaling for job completion
  73. std::condition_variable CompletionCondition;
  74. /// Keep track of the number of thread actually busy
  75. unsigned ActiveThreads = 0;
  76. #if LLVM_ENABLE_THREADS // avoids warning for unused variable
  77. /// Signal for the destruction of the pool, asking thread to exit.
  78. bool EnableFlag = true;
  79. #endif
  80. unsigned ThreadCount;
  81. };
  82. }
  83. #endif // LLVM_SUPPORT_THREADPOOL_H