diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:12:36 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:12:36 +0000 | 
| commit | ef5d0b5e97ec8e6fa395d377b09aa7755e345b4f (patch) | |
| tree | 27916256fdeeb57d10d2f3d6948be5d71a703215 /include/lldb/Host/TaskPool.h | |
| parent | 76e0736e7fcfeb179779e49c05604464b1ccd704 (diff) | |
Notes
Diffstat (limited to 'include/lldb/Host/TaskPool.h')
| -rw-r--r-- | include/lldb/Host/TaskPool.h | 98 | 
1 files changed, 98 insertions, 0 deletions
diff --git a/include/lldb/Host/TaskPool.h b/include/lldb/Host/TaskPool.h new file mode 100644 index 0000000000000..13076e7eb70bd --- /dev/null +++ b/include/lldb/Host/TaskPool.h @@ -0,0 +1,98 @@ +//===--------------------- TaskPool.h ---------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_TaskPool_h_ +#define utility_TaskPool_h_ + +#include "llvm/ADT/STLExtras.h" +#include <functional> // for bind, function +#include <future> +#include <list> +#include <memory>      // for make_shared +#include <mutex>       // for mutex, unique_lock, condition_variable +#include <type_traits> // for forward, result_of, move + +namespace lldb_private { + +// Global TaskPool class for running tasks in parallel on a set of worker thread +// created the first +// time the task pool is used. The TaskPool provide no guarantee about the order +// the task will be run +// and about what tasks will run in parallel. None of the task added to the task +// pool should block +// on something (mutex, future, condition variable) what will be set only by the +// completion of an +// other task on the task pool as they may run on the same thread sequentally. +class TaskPool { +public: +  // Add a new task to the task pool and return a std::future belonging to the +  // newly created task. +  // The caller of this function has to wait on the future for this task to +  // complete. +  template <typename F, typename... Args> +  static std::future<typename std::result_of<F(Args...)>::type> +  AddTask(F &&f, Args &&... args); + +  // Run all of the specified tasks on the task pool and wait until all of them +  // are finished +  // before returning. This method is intended to be used for small number tasks +  // where listing +  // them as function arguments is acceptable. For running large number of tasks +  // you should use +  // AddTask for each task and then call wait() on each returned future. +  template <typename... T> static void RunTasks(T &&... tasks); + +private: +  TaskPool() = delete; + +  template <typename... T> struct RunTaskImpl; + +  static void AddTaskImpl(std::function<void()> &&task_fn); +}; + +template <typename F, typename... Args> +std::future<typename std::result_of<F(Args...)>::type> +TaskPool::AddTask(F &&f, Args &&... args) { +  auto task_sp = std::make_shared< +      std::packaged_task<typename std::result_of<F(Args...)>::type()>>( +      std::bind(std::forward<F>(f), std::forward<Args>(args)...)); + +  AddTaskImpl([task_sp]() { (*task_sp)(); }); + +  return task_sp->get_future(); +} + +template <typename... T> void TaskPool::RunTasks(T &&... tasks) { +  RunTaskImpl<T...>::Run(std::forward<T>(tasks)...); +} + +template <typename Head, typename... Tail> +struct TaskPool::RunTaskImpl<Head, Tail...> { +  static void Run(Head &&h, Tail &&... t) { +    auto f = AddTask(std::forward<Head>(h)); +    RunTaskImpl<Tail...>::Run(std::forward<Tail>(t)...); +    f.wait(); +  } +}; + +template <> struct TaskPool::RunTaskImpl<> { +  static void Run() {} +}; + +// Run 'func' on every value from begin .. end-1.  Each worker will grab +// 'batch_size' numbers at a time to work on, so for very fast functions, batch +// should be large enough to avoid too much cache line contention. +void TaskMapOverInt(size_t begin, size_t end, +                    const llvm::function_ref<void(size_t)> &func); + +unsigned GetHardwareConcurrencyHint(); + +} // namespace lldb_private + +#endif // #ifndef utility_TaskPool_h_  | 
