[lld] r242004 - Fix lld tests with LLVM_ENABLE_THREADS disabled.

Nico Weber nicolasweber at gmx.de
Sun Jul 12 17:51:44 PDT 2015


Author: nico
Date: Sun Jul 12 19:51:43 2015
New Revision: 242004

URL: http://llvm.org/viewvc/llvm-project?rev=242004&view=rev
Log:
Fix lld tests with LLVM_ENABLE_THREADS disabled.

With LLVM_ENABLE_THREADS disabled, all the llvm code assumes that it runs on
a single thread and doesn't use any mutexes.  lld still spawned lots of threads
in that case and called into llvm, assuming that llvm is thread-safe.

As fix, let lld use only a single thread if LLVM_ENABLE_THREADS is disabled.
I left in all the mutexes in lld. That means lld is a bit slower than
necessary in single-thread mode, but that's probably worth the simpler code.

Modified:
    lld/trunk/include/lld/Core/Parallel.h

Modified: lld/trunk/include/lld/Core/Parallel.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Parallel.h?rev=242004&r1=242003&r2=242004&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Parallel.h (original)
+++ lld/trunk/include/lld/Core/Parallel.h Sun Jul 12 19:51:43 2015
@@ -104,6 +104,9 @@ private:
   std::condition_variable _cond;
 };
 
+// Classes in this namespace are implementation details of this header.
+namespace internal {
+
 /// \brief An abstract class that takes closures and runs them asynchronously.
 class Executor {
 public:
@@ -111,6 +114,45 @@ public:
   virtual void add(std::function<void()> func) = 0;
 };
 
+#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
+class SyncExecutor : public Executor {
+public:
+  virtual void add(std::function<void()> func) {
+    func();
+  }
+};
+
+inline Executor *getDefaultExecutor() {
+  static SyncExecutor exec;
+  return &exec;
+}
+#elif defined(_MSC_VER)
+/// \brief An Executor that runs tasks via ConcRT.
+class ConcRTExecutor : public Executor {
+  struct Taskish {
+    Taskish(std::function<void()> task) : _task(task) {}
+
+    std::function<void()> _task;
+
+    static void run(void *p) {
+      Taskish *self = static_cast<Taskish *>(p);
+      self->_task();
+      concurrency::Free(self);
+    }
+  };
+
+public:
+  virtual void add(std::function<void()> func) {
+    Concurrency::CurrentScheduler::ScheduleTask(Taskish::run,
+        new (concurrency::Alloc(sizeof(Taskish))) Taskish(func));
+  }
+};
+
+inline Executor *getDefaultExecutor() {
+  static ConcRTExecutor exec;
+  return &exec;
+}
+#else
 /// \brief An implementation of an Executor that runs closures on a thread pool
 ///   in filo order.
 class ThreadPoolExecutor : public Executor {
@@ -169,39 +211,14 @@ private:
   Latch _done;
 };
 
-#ifdef _MSC_VER
-/// \brief An Executor that runs tasks via ConcRT.
-class ConcRTExecutor : public Executor {
-  struct Taskish {
-    Taskish(std::function<void()> task) : _task(task) {}
-
-    std::function<void()> _task;
-
-    static void run(void *p) {
-      Taskish *self = static_cast<Taskish *>(p);
-      self->_task();
-      concurrency::Free(self);
-    }
-  };
-
-public:
-  virtual void add(std::function<void()> func) {
-    Concurrency::CurrentScheduler::ScheduleTask(Taskish::run,
-        new (concurrency::Alloc(sizeof(Taskish))) Taskish(func));
-  }
-};
-
-inline Executor *getDefaultExecutor() {
-  static ConcRTExecutor exec;
-  return &exec;
-}
-#else
 inline Executor *getDefaultExecutor() {
   static ThreadPoolExecutor exec;
   return &exec;
 }
 #endif
 
+}  // namespace internal
+
 /// \brief Allows launching a number of tasks and waiting for them to finish
 ///   either explicitly via sync() or implicitly on destruction.
 class TaskGroup {
@@ -210,7 +227,7 @@ class TaskGroup {
 public:
   void spawn(std::function<void()> f) {
     _latch.inc();
-    getDefaultExecutor()->add([&, f] {
+    internal::getDefaultExecutor()->add([&, f] {
       f();
       _latch.dec();
     });
@@ -219,7 +236,15 @@ public:
   void sync() const { _latch.sync(); }
 };
 
-#ifdef _MSC_VER
+#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
+template <class RandomAccessIterator, class Comp>
+void parallel_sort(
+    RandomAccessIterator start, RandomAccessIterator end,
+    const Comp &comp = std::less<
+        typename std::iterator_traits<RandomAccessIterator>::value_type>()) {
+  std::sort(start, end, comp);
+}
+#elif defined(_MSC_VER)
 // Use ppl parallel_sort on Windows.
 template <class RandomAccessIterator, class Comp>
 void parallel_sort(
@@ -286,7 +311,12 @@ template <class T> void parallel_sort(T
   parallel_sort(start, end, std::less<T>());
 }
 
-#ifdef _MSC_VER
+#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
+template <class Iterator, class Func>
+void parallel_for_each(Iterator begin, Iterator end, Func func) {
+  std::for_each(begin, end, func);
+}
+#elif defined(_MSC_VER)
 // Use ppl parallel_for_each on Windows.
 template <class Iterator, class Func>
 void parallel_for_each(Iterator begin, Iterator end, Func func) {





More information about the llvm-commits mailing list