summaryrefslogtreecommitdiff
path: root/include/lldb/Utility/TaskPool.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Utility/TaskPool.h')
-rw-r--r--include/lldb/Utility/TaskPool.h108
1 files changed, 5 insertions, 103 deletions
diff --git a/include/lldb/Utility/TaskPool.h b/include/lldb/Utility/TaskPool.h
index fb936bbb739a..87b8824f9226 100644
--- a/include/lldb/Utility/TaskPool.h
+++ b/include/lldb/Utility/TaskPool.h
@@ -53,50 +53,6 @@ private:
static void AddTaskImpl(std::function<void()> &&task_fn);
};
-// Wrapper class around the global TaskPool implementation to make it possible
-// to create a set of
-// tasks and then wait for the tasks to be completed by the
-// WaitForNextCompletedTask call. This
-// class should be used when WaitForNextCompletedTask is needed because this
-// class add no other
-// extra functionality to the TaskPool class and it have a very minor
-// performance overhead.
-template <typename T> // The return type of the tasks what will be added to this
- // task runner
- class TaskRunner {
-public:
- // Add a task to the task runner what will also add the task to the global
- // TaskPool. The
- // function doesn't return the std::future for the task because it will be
- // supplied by the
- // WaitForNextCompletedTask after the task is completed.
- template <typename F, typename... Args> void AddTask(F &&f, Args &&... args);
-
- // Wait for the next task in this task runner to finish and then return the
- // std::future what
- // belongs to the finished task. If there is no task in this task runner
- // (neither pending nor
- // comleted) then this function will return an invalid future. Usually this
- // function should be
- // called in a loop processing the results of the tasks until it returns an
- // invalid std::future
- // what means that all task in this task runner is completed.
- std::future<T> WaitForNextCompletedTask();
-
- // Convenience method to wait for all task in this TaskRunner to finish. Do
- // NOT use this class
- // just because of this method. Use TaskPool instead and wait for each
- // std::future returned by
- // AddTask in a loop.
- void WaitForAllTasks();
-
-private:
- std::list<std::future<T>> m_ready;
- std::list<std::future<T>> m_pending;
- std::mutex m_mutex;
- std::condition_variable m_cv;
-};
-
template <typename F, typename... Args>
std::future<typename std::result_of<F(Args...)>::type>
TaskPool::AddTask(F &&f, Args &&... args) {
@@ -126,64 +82,10 @@ template <> struct TaskPool::RunTaskImpl<> {
static void Run() {}
};
-template <typename T>
-template <typename F, typename... Args>
-void TaskRunner<T>::AddTask(F &&f, Args &&... args) {
- std::unique_lock<std::mutex> lock(m_mutex);
- auto it = m_pending.emplace(m_pending.end());
- *it = std::move(TaskPool::AddTask(
- [this, it](F f, Args... args) {
- T &&r = f(std::forward<Args>(args)...);
-
- std::unique_lock<std::mutex> lock(this->m_mutex);
- this->m_ready.splice(this->m_ready.end(), this->m_pending, it);
- lock.unlock();
-
- this->m_cv.notify_one();
- return r;
- },
- std::forward<F>(f), std::forward<Args>(args)...));
-}
-
-template <>
-template <typename F, typename... Args>
-void TaskRunner<void>::AddTask(F &&f, Args &&... args) {
- std::unique_lock<std::mutex> lock(m_mutex);
- auto it = m_pending.emplace(m_pending.end());
- *it = std::move(TaskPool::AddTask(
- [this, it](F f, Args... args) {
- f(std::forward<Args>(args)...);
-
- std::unique_lock<std::mutex> lock(this->m_mutex);
- this->m_ready.emplace_back(std::move(*it));
- this->m_pending.erase(it);
- lock.unlock();
-
- this->m_cv.notify_one();
- },
- std::forward<F>(f), std::forward<Args>(args)...));
-}
-
-template <typename T> std::future<T> TaskRunner<T>::WaitForNextCompletedTask() {
- std::unique_lock<std::mutex> lock(m_mutex);
- if (m_ready.empty() && m_pending.empty())
- return std::future<T>(); // No more tasks
-
- if (m_ready.empty())
- m_cv.wait(lock, [this]() { return !this->m_ready.empty(); });
-
- std::future<T> res = std::move(m_ready.front());
- m_ready.pop_front();
-
- lock.unlock();
- res.wait();
-
- return std::move(res);
-}
-
-template <typename T> void TaskRunner<T>::WaitForAllTasks() {
- while (WaitForNextCompletedTask().valid())
- ;
-}
+// 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,
+ std::function<void(size_t)> const &func);
#endif // #ifndef utility_TaskPool_h_