This revision was automatically updated to reflect the committed changes.
Closed by commit rL313637: Use ThreadLauncher to launch TaskPool threads 
(authored by fjricci).

Changed prior to commit:
  https://reviews.llvm.org/D37930?vs=115691&id=115844#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D37930

Files:
  lldb/trunk/include/lldb/Host/TaskPool.h
  lldb/trunk/include/lldb/Utility/TaskPool.h
  lldb/trunk/lldb.xcodeproj/project.pbxproj
  lldb/trunk/source/Host/CMakeLists.txt
  lldb/trunk/source/Host/common/TaskPool.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/trunk/source/Utility/CMakeLists.txt
  lldb/trunk/source/Utility/TaskPool.cpp
  lldb/trunk/unittests/Host/CMakeLists.txt
  lldb/trunk/unittests/Host/TaskPoolTest.cpp
  lldb/trunk/unittests/Utility/CMakeLists.txt
  lldb/trunk/unittests/Utility/TaskPoolTest.cpp

Index: lldb/trunk/unittests/Host/TaskPoolTest.cpp
===================================================================
--- lldb/trunk/unittests/Host/TaskPoolTest.cpp
+++ lldb/trunk/unittests/Host/TaskPoolTest.cpp
@@ -0,0 +1,43 @@
+#include "gtest/gtest.h"
+
+#include "lldb/Host/TaskPool.h"
+
+TEST(TaskPoolTest, AddTask) {
+  auto fn = [](int x) { return x * x + 1; };
+
+  auto f1 = TaskPool::AddTask(fn, 1);
+  auto f2 = TaskPool::AddTask(fn, 2);
+  auto f3 = TaskPool::AddTask(fn, 3);
+  auto f4 = TaskPool::AddTask(fn, 4);
+
+  ASSERT_EQ(10, f3.get());
+  ASSERT_EQ(2, f1.get());
+  ASSERT_EQ(17, f4.get());
+  ASSERT_EQ(5, f2.get());
+}
+
+TEST(TaskPoolTest, RunTasks) {
+  std::vector<int> r(4);
+
+  auto fn = [](int x, int &y) { y = x * x + 1; };
+
+  TaskPool::RunTasks([fn, &r]() { fn(1, r[0]); }, [fn, &r]() { fn(2, r[1]); },
+                     [fn, &r]() { fn(3, r[2]); }, [fn, &r]() { fn(4, r[3]); });
+
+  ASSERT_EQ(2, r[0]);
+  ASSERT_EQ(5, r[1]);
+  ASSERT_EQ(10, r[2]);
+  ASSERT_EQ(17, r[3]);
+}
+
+TEST(TaskPoolTest, TaskMap) {
+  int data[4];
+  auto fn = [&data](int x) { data[x] = x * x; };
+
+  TaskMapOverInt(0, 4, fn);
+
+  ASSERT_EQ(data[0], 0);
+  ASSERT_EQ(data[1], 1);
+  ASSERT_EQ(data[2], 4);
+  ASSERT_EQ(data[3], 9);
+}
Index: lldb/trunk/unittests/Host/CMakeLists.txt
===================================================================
--- lldb/trunk/unittests/Host/CMakeLists.txt
+++ lldb/trunk/unittests/Host/CMakeLists.txt
@@ -6,6 +6,7 @@
   SocketAddressTest.cpp
   SocketTest.cpp
   SymbolsTest.cpp
+  TaskPoolTest.cpp
 )
 
 if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
Index: lldb/trunk/unittests/Utility/CMakeLists.txt
===================================================================
--- lldb/trunk/unittests/Utility/CMakeLists.txt
+++ lldb/trunk/unittests/Utility/CMakeLists.txt
@@ -8,7 +8,6 @@
   StatusTest.cpp
   StringExtractorTest.cpp
   StructuredDataTest.cpp
-  TaskPoolTest.cpp
   TildeExpressionResolverTest.cpp
   TimeoutTest.cpp
   TimerTest.cpp
Index: lldb/trunk/source/Utility/CMakeLists.txt
===================================================================
--- lldb/trunk/source/Utility/CMakeLists.txt
+++ lldb/trunk/source/Utility/CMakeLists.txt
@@ -29,7 +29,6 @@
   StringLexer.cpp
   StringList.cpp
   StructuredData.cpp
-  TaskPool.cpp
   TildeExpressionResolver.cpp
   Timer.cpp
   UserID.cpp
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -53,7 +53,7 @@
 
 #include "lldb/Target/Language.h"
 
-#include "lldb/Utility/TaskPool.h"
+#include "lldb/Host/TaskPool.h"
 
 #include "DWARFASTParser.h"
 #include "DWARFASTParserClang.h"
Index: lldb/trunk/source/Host/CMakeLists.txt
===================================================================
--- lldb/trunk/source/Host/CMakeLists.txt
+++ lldb/trunk/source/Host/CMakeLists.txt
@@ -31,6 +31,7 @@
   common/SoftwareBreakpoint.cpp
   common/StringConvert.cpp
   common/Symbols.cpp
+  common/TaskPool.cpp
   common/TCPSocket.cpp
   common/Terminal.cpp
   common/ThreadLauncher.cpp
Index: lldb/trunk/source/Host/common/TaskPool.cpp
===================================================================
--- lldb/trunk/source/Host/common/TaskPool.cpp
+++ lldb/trunk/source/Host/common/TaskPool.cpp
@@ -0,0 +1,109 @@
+//===--------------------- TaskPool.cpp -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/TaskPool.h"
+#include "lldb/Host/ThreadLauncher.h"
+
+#include <cstdint> // for uint32_t
+#include <queue>   // for queue
+#include <thread>  // for thread
+
+namespace {
+class TaskPoolImpl {
+public:
+  static TaskPoolImpl &GetInstance();
+
+  void AddTask(std::function<void()> &&task_fn);
+
+private:
+  TaskPoolImpl();
+
+  static lldb::thread_result_t WorkerPtr(void *pool);
+
+  static void Worker(TaskPoolImpl *pool);
+
+  std::queue<std::function<void()>> m_tasks;
+  std::mutex m_tasks_mutex;
+  uint32_t m_thread_count;
+};
+
+} // end of anonymous namespace
+
+TaskPoolImpl &TaskPoolImpl::GetInstance() {
+  static TaskPoolImpl g_task_pool_impl;
+  return g_task_pool_impl;
+}
+
+void TaskPool::AddTaskImpl(std::function<void()> &&task_fn) {
+  TaskPoolImpl::GetInstance().AddTask(std::move(task_fn));
+}
+
+TaskPoolImpl::TaskPoolImpl() : m_thread_count(0) {}
+
+void TaskPoolImpl::AddTask(std::function<void()> &&task_fn) {
+  static const uint32_t max_threads = std::thread::hardware_concurrency();
+  const size_t min_stack_size = 8 * 1024 * 1024;
+
+  std::unique_lock<std::mutex> lock(m_tasks_mutex);
+  m_tasks.emplace(std::move(task_fn));
+  if (m_thread_count < max_threads) {
+    m_thread_count++;
+    // Note that this detach call needs to happen with the m_tasks_mutex held.
+    // This prevents the thread
+    // from exiting prematurely and triggering a linux libc bug
+    // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
+    lldb_private::ThreadLauncher::LaunchThread("task-pool.worker", WorkerPtr,
+                                               this, nullptr, min_stack_size)
+        .Release();
+  }
+}
+
+lldb::thread_result_t TaskPoolImpl::WorkerPtr(void *pool) {
+  Worker((TaskPoolImpl *)pool);
+  return 0;
+}
+
+void TaskPoolImpl::Worker(TaskPoolImpl *pool) {
+  while (true) {
+    std::unique_lock<std::mutex> lock(pool->m_tasks_mutex);
+    if (pool->m_tasks.empty()) {
+      pool->m_thread_count--;
+      break;
+    }
+
+    std::function<void()> f = pool->m_tasks.front();
+    pool->m_tasks.pop();
+    lock.unlock();
+
+    f();
+  }
+}
+
+void TaskMapOverInt(size_t begin, size_t end,
+                    const llvm::function_ref<void(size_t)> &func) {
+  std::atomic<size_t> idx{begin};
+  size_t num_workers =
+      std::min<size_t>(end, std::thread::hardware_concurrency());
+
+  auto wrapper = [&idx, end, &func]() {
+    while (true) {
+      size_t i = idx.fetch_add(1);
+      if (i >= end)
+        break;
+      func(i);
+    }
+  };
+
+  std::vector<std::future<void>> futures;
+  futures.reserve(num_workers);
+  for (size_t i = 0; i < num_workers; i++)
+    futures.push_back(TaskPool::AddTask(wrapper));
+  for (size_t i = 0; i < num_workers; i++)
+    futures[i].wait();
+}
Index: lldb/trunk/include/lldb/Host/TaskPool.h
===================================================================
--- lldb/trunk/include/lldb/Host/TaskPool.h
+++ lldb/trunk/include/lldb/Host/TaskPool.h
@@ -0,0 +1,92 @@
+//===--------------------- 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
+
+// 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);
+
+#endif // #ifndef utility_TaskPool_h_
Index: lldb/trunk/lldb.xcodeproj/project.pbxproj
===================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj
@@ -2664,8 +2664,8 @@
 		6D99A3621BBC2F3200979793 /* ArmUnwindInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ArmUnwindInfo.cpp; path = source/Symbol/ArmUnwindInfo.cpp; sourceTree = "<group>"; };
 		6D9AB3DC1BB2B74E003F2289 /* TypeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeMap.cpp; path = source/Symbol/TypeMap.cpp; sourceTree = "<group>"; };
 		6D9AB3DE1BB2B76B003F2289 /* TypeMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeMap.h; path = include/lldb/Symbol/TypeMap.h; sourceTree = "<group>"; };
-		6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TaskPool.cpp; path = source/Utility/TaskPool.cpp; sourceTree = "<group>"; };
-		6DEC6F3A1BD66D950091ABA6 /* TaskPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaskPool.h; path = include/lldb/Utility/TaskPool.h; sourceTree = "<group>"; };
+		6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TaskPool.cpp; path = source/Host/common/TaskPool.cpp; sourceTree = "<group>"; };
+		6DEC6F3A1BD66D950091ABA6 /* TaskPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaskPool.h; path = include/lldb/Host/TaskPool.h; sourceTree = "<group>"; };
 		8C26C4241C3EA4340031DF7C /* TSanRuntime.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TSanRuntime.cpp; path = TSan/TSanRuntime.cpp; sourceTree = "<group>"; };
 		8C26C4251C3EA4340031DF7C /* TSanRuntime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TSanRuntime.h; path = TSan/TSanRuntime.h; sourceTree = "<group>"; };
 		8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp; sourceTree = "<group>"; };
@@ -4413,8 +4413,6 @@
 				AFEC3361194A8ABA00FF05C6 /* StructuredData.cpp */,
 				94BA8B6E176F8CA0005A91B5 /* Range.h */,
 				94BA8B6C176F8C9B005A91B5 /* Range.cpp */,
-				6DEC6F3A1BD66D950091ABA6 /* TaskPool.h */,
-				6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */,
 				AFF8FF0B1E779D4B003830EF /* TildeExpressionResolver.cpp */,
 				AFF8FF0D1E779D51003830EF /* TildeExpressionResolver.h */,
 				26BC7D7E10F1B77400F91463 /* Timer.h */,
@@ -5248,6 +5246,8 @@
 				267A47F21B14115A0021A5BC /* SoftwareBreakpoint.h */,
 				232CB613191E00CC00EF39FC /* SoftwareBreakpoint.cpp */,
 				2689B0A4113EE3CD00A4AEDB /* Symbols.h */,
+				6DEC6F3A1BD66D950091ABA6 /* TaskPool.h */,
+				6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */,
 				268DA871130095D000C9483A /* Terminal.h */,
 				3FDFED2319BA6D55009756A7 /* ThreadLauncher.h */,
 				267A48031B1416080021A5BC /* XML.h */,
Index: lldb/trunk/unittests/Utility/TaskPoolTest.cpp
===================================================================
--- lldb/trunk/unittests/Utility/TaskPoolTest.cpp
+++ lldb/trunk/unittests/Utility/TaskPoolTest.cpp
@@ -1,43 +0,0 @@
-#include "gtest/gtest.h"
-
-#include "lldb/Utility/TaskPool.h"
-
-TEST(TaskPoolTest, AddTask) {
-  auto fn = [](int x) { return x * x + 1; };
-
-  auto f1 = TaskPool::AddTask(fn, 1);
-  auto f2 = TaskPool::AddTask(fn, 2);
-  auto f3 = TaskPool::AddTask(fn, 3);
-  auto f4 = TaskPool::AddTask(fn, 4);
-
-  ASSERT_EQ(10, f3.get());
-  ASSERT_EQ(2, f1.get());
-  ASSERT_EQ(17, f4.get());
-  ASSERT_EQ(5, f2.get());
-}
-
-TEST(TaskPoolTest, RunTasks) {
-  std::vector<int> r(4);
-
-  auto fn = [](int x, int &y) { y = x * x + 1; };
-
-  TaskPool::RunTasks([fn, &r]() { fn(1, r[0]); }, [fn, &r]() { fn(2, r[1]); },
-                     [fn, &r]() { fn(3, r[2]); }, [fn, &r]() { fn(4, r[3]); });
-
-  ASSERT_EQ(2, r[0]);
-  ASSERT_EQ(5, r[1]);
-  ASSERT_EQ(10, r[2]);
-  ASSERT_EQ(17, r[3]);
-}
-
-TEST(TaskPoolTest, TaskMap) {
-  int data[4];
-  auto fn = [&data](int x) { data[x] = x * x; };
-
-  TaskMapOverInt(0, 4, fn);
-
-  ASSERT_EQ(data[0], 0);
-  ASSERT_EQ(data[1], 1);
-  ASSERT_EQ(data[2], 4);
-  ASSERT_EQ(data[3], 9);
-}
Index: lldb/trunk/source/Utility/TaskPool.cpp
===================================================================
--- lldb/trunk/source/Utility/TaskPool.cpp
+++ lldb/trunk/source/Utility/TaskPool.cpp
@@ -1,98 +0,0 @@
-//===--------------------- TaskPool.cpp -------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/TaskPool.h"
-
-#include <cstdint> // for uint32_t
-#include <queue>   // for queue
-#include <thread>  // for thread
-
-namespace {
-class TaskPoolImpl {
-public:
-  static TaskPoolImpl &GetInstance();
-
-  void AddTask(std::function<void()> &&task_fn);
-
-private:
-  TaskPoolImpl();
-
-  static void Worker(TaskPoolImpl *pool);
-
-  std::queue<std::function<void()>> m_tasks;
-  std::mutex m_tasks_mutex;
-  uint32_t m_thread_count;
-};
-
-} // end of anonymous namespace
-
-TaskPoolImpl &TaskPoolImpl::GetInstance() {
-  static TaskPoolImpl g_task_pool_impl;
-  return g_task_pool_impl;
-}
-
-void TaskPool::AddTaskImpl(std::function<void()> &&task_fn) {
-  TaskPoolImpl::GetInstance().AddTask(std::move(task_fn));
-}
-
-TaskPoolImpl::TaskPoolImpl() : m_thread_count(0) {}
-
-void TaskPoolImpl::AddTask(std::function<void()> &&task_fn) {
-  static const uint32_t max_threads = std::thread::hardware_concurrency();
-
-  std::unique_lock<std::mutex> lock(m_tasks_mutex);
-  m_tasks.emplace(std::move(task_fn));
-  if (m_thread_count < max_threads) {
-    m_thread_count++;
-    // Note that this detach call needs to happen with the m_tasks_mutex held.
-    // This prevents the thread
-    // from exiting prematurely and triggering a linux libc bug
-    // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
-    std::thread(Worker, this).detach();
-  }
-}
-
-void TaskPoolImpl::Worker(TaskPoolImpl *pool) {
-  while (true) {
-    std::unique_lock<std::mutex> lock(pool->m_tasks_mutex);
-    if (pool->m_tasks.empty()) {
-      pool->m_thread_count--;
-      break;
-    }
-
-    std::function<void()> f = pool->m_tasks.front();
-    pool->m_tasks.pop();
-    lock.unlock();
-
-    f();
-  }
-}
-
-void TaskMapOverInt(size_t begin, size_t end,
-                    const llvm::function_ref<void(size_t)> &func) {
-  std::atomic<size_t> idx{begin};
-  size_t num_workers =
-      std::min<size_t>(end, std::thread::hardware_concurrency());
-
-  auto wrapper = [&idx, end, &func]() {
-    while (true) {
-      size_t i = idx.fetch_add(1);
-      if (i >= end)
-        break;
-      func(i);
-    }
-  };
-
-  std::vector<std::future<void>> futures;
-  futures.reserve(num_workers);
-  for (size_t i = 0; i < num_workers; i++)
-    futures.push_back(TaskPool::AddTask(wrapper));
-  for (size_t i = 0; i < num_workers; i++)
-    futures[i].wait();
-}
Index: lldb/trunk/include/lldb/Utility/TaskPool.h
===================================================================
--- lldb/trunk/include/lldb/Utility/TaskPool.h
+++ lldb/trunk/include/lldb/Utility/TaskPool.h
@@ -1,92 +0,0 @@
-//===--------------------- 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
-
-// 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);
-
-#endif // #ifndef utility_TaskPool_h_
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to