Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/ThreadPool.h
Line
Count
Source
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
13
#ifndef LLVM_SUPPORT_THREAD_POOL_H
14
#define LLVM_SUPPORT_THREAD_POOL_H
15
16
#include "llvm/Config/llvm-config.h"
17
#include "llvm/Support/thread.h"
18
19
#include <future>
20
21
#include <atomic>
22
#include <condition_variable>
23
#include <functional>
24
#include <memory>
25
#include <mutex>
26
#include <queue>
27
#include <utility>
28
29
namespace llvm {
30
31
/// A ThreadPool for asynchronous parallel execution on a defined number of
32
/// threads.
33
///
34
/// The pool keeps a vector of threads alive, waiting on a condition variable
35
/// for some work to become available.
36
class ThreadPool {
37
public:
38
  using TaskTy = std::function<void()>;
39
  using PackagedTaskTy = std::packaged_task<void()>;
40
41
  /// Construct a pool with the number of threads found by
42
  /// hardware_concurrency().
43
  ThreadPool();
44
45
  /// Construct a pool of \p ThreadCount threads
46
  ThreadPool(unsigned ThreadCount);
47
48
  /// Blocking destructor: the pool will wait for all the threads to complete.
49
  ~ThreadPool();
50
51
  /// Asynchronous submission of a task to the pool. The returned future can be
52
  /// used to wait for the task to finish and is *non-blocking* on destruction.
53
  template <typename Function, typename... Args>
54
287
  inline std::shared_future<void> async(Function &&F, Args &&... ArgList) {
55
287
    auto Task =
56
287
        std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...);
57
287
    return asyncImpl(std::move(Task));
58
287
  }
LTO.cpp:std::__1::shared_future<void> llvm::ThreadPool::async<(anonymous namespace)::InProcessThinBackend::start(unsigned int, llvm::BitcodeModule, llvm::StringMap<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> >, llvm::MallocAllocator> const&, std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> > const&, std::__1::map<unsigned long long, llvm::GlobalValue::LinkageTypes, std::__1::less<unsigned long long>, std::__1::allocator<std::__1::pair<unsigned long long const, llvm::GlobalValue::LinkageTypes> > > const&, llvm::MapVector<llvm::StringRef, llvm::BitcodeModule, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, llvm::BitcodeModule>, std::__1::allocator<std::__1::pair<llvm::StringRef, llvm::BitcodeModule> > > >&)::'lambda'(llvm::BitcodeModule, llvm::ModuleSummaryIndex&, llvm::StringMap<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> >, llvm::MallocAllocator> const&, std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> > const&, std::__1::map<unsigned long long, llvm::GlobalValue::LinkageTypes, std::__1::less<unsigned long long>, std::__1::allocator<std::__1::pair<unsigned long long const, llvm::GlobalValue::LinkageTypes> > > const&, llvm::DenseMap<unsigned long long, llvm::GlobalValueSummary*, llvm::DenseMapInfo<unsigned long long>, llvm::detail::DenseMapPair<unsigned long long, llvm::GlobalValueSummary*> > const&, llvm::MapVector<llvm::StringRef, llvm::BitcodeModule, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, llvm::BitcodeModule>, std::__1::allocator<std::__1::pair<llvm::StringRef, llvm::BitcodeModule> > > >&), llvm::BitcodeModule&, std::__1::reference_wrapper<llvm::ModuleSummaryIndex>, std::__1::reference_wrapper<llvm::StringMap<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> >, llvm::MallocAllocator> const>, std::__1::reference_wrapper<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> > const>, std::__1::reference_wrapper<std::__1::map<unsigned long long, llvm::GlobalValue::LinkageTypes, std::__1::less<unsigned long long>, std::__1::allocator<std::__1::pair<unsigned long long const, llvm::GlobalValue::LinkageTypes> > > const>, std::__1::reference_wrapper<llvm::DenseMap<unsigned long long, llvm::GlobalValueSummary*, llvm::DenseMapInfo<unsigned long long>, llvm::detail::DenseMapPair<unsigned long long, llvm::GlobalValueSummary*> > const>, std::__1::reference_wrapper<llvm::MapVector<llvm::StringRef, llvm::BitcodeModule, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, llvm::BitcodeModule>, std::__1::allocator<std::__1::pair<llvm::StringRef, llvm::BitcodeModule> > > > > >((anonymous namespace)::InProcessThinBackend::start(unsigned int, llvm::BitcodeModule, llvm::StringMap<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> >, llvm::MallocAllocator> const&, std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> > const&, std::__1::map<unsigned long long, llvm::GlobalValue::LinkageTypes, std::__1::less<unsigned long long>, std::__1::allocator<std::__1::pair<unsigned long long const, llvm::GlobalValue::LinkageTypes> > > const&, llvm::MapVector<llvm::StringRef, llvm::BitcodeModule, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, llvm::BitcodeModule>, std::__1::allocator<std::__1::pair<llvm::StringRef, llvm::BitcodeModule> > > >&)::'lambda'(llvm::BitcodeModule, llvm::ModuleSummaryIndex&, llvm::StringMap<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> >, llvm::MallocAllocator> const&, std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> > const&, std::__1::map<unsigned long long, llvm::GlobalValue::LinkageTypes, std::__1::less<unsigned long long>, std::__1::allocator<std::__1::pair<unsigned long long const, llvm::GlobalValue::LinkageTypes> > > const&, llvm::DenseMap<unsigned long long, llvm::GlobalValueSummary*, llvm::DenseMapInfo<unsigned long long>, llvm::detail::DenseMapPair<unsigned long long, llvm::GlobalValueSummary*> > const&, llvm::MapVector<llvm::StringRef, llvm::BitcodeModule, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, llvm::BitcodeModule>, std::__1::allocator<std::__1::pair<llvm::StringRef, llvm::BitcodeModule> > > >&)&&, llvm::BitcodeModule&&&, std::__1::reference_wrapper<llvm::ModuleSummaryIndex>&&, std::__1::reference_wrapper<llvm::StringMap<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> >, llvm::MallocAllocator> const>&&, std::__1::reference_wrapper<std::__1::unordered_set<unsigned long long, std::__1::hash<unsigned long long>, std::__1::equal_to<unsigned long long>, std::__1::allocator<unsigned long long> > const>&&, std::__1::reference_wrapper<std::__1::map<unsigned long long, llvm::GlobalValue::LinkageTypes, std::__1::less<unsigned long long>, std::__1::allocator<std::__1::pair<unsigned long long const, llvm::GlobalValue::LinkageTypes> > > const>&&, std::__1::reference_wrapper<llvm::DenseMap<unsigned long long, llvm::GlobalValueSummary*, llvm::DenseMapInfo<unsigned long long>, llvm::detail::DenseMapPair<unsigned long long, llvm::GlobalValueSummary*> > const>&&, std::__1::reference_wrapper<llvm::MapVector<llvm::StringRef, llvm::BitcodeModule, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, llvm::BitcodeModule>, std::__1::allocator<std::__1::pair<llvm::StringRef, llvm::BitcodeModule> > > > >&&)
Line
Count
Source
54
279
  inline std::shared_future<void> async(Function &&F, Args &&... ArgList) {
55
279
    auto Task =
56
279
        std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...);
57
279
    return asyncImpl(std::move(Task));
58
279
  }
LTOBackend.cpp:std::__1::shared_future<void> llvm::ThreadPool::async<(anonymous namespace)::splitCodeGen(llvm::lto::Config&, llvm::TargetMachine*, std::__1::function<std::__1::unique_ptr<llvm::lto::NativeObjectStream, std::__1::default_delete<llvm::lto::NativeObjectStream> > (unsigned int)>, unsigned int, std::__1::unique_ptr<llvm::Module, std::__1::default_delete<llvm::Module> >)::$_5::operator()(std::__1::unique_ptr<llvm::Module, std::__1::default_delete<llvm::Module> >) const::'lambda'(llvm::SmallString<0u> const&, unsigned int), llvm::SmallString<0u>, unsigned int>((anonymous namespace)::splitCodeGen(llvm::lto::Config&, llvm::TargetMachine*, std::__1::function<std::__1::unique_ptr<llvm::lto::NativeObjectStream, std::__1::default_delete<llvm::lto::NativeObjectStream> > (unsigned int)>, unsigned int, std::__1::unique_ptr<llvm::Module, std::__1::default_delete<llvm::Module> >)::$_5::operator()(std::__1::unique_ptr<llvm::Module, std::__1::default_delete<llvm::Module> >) const::'lambda'(llvm::SmallString<0u> const&, unsigned int)&&, llvm::SmallString<0u>&&, unsigned int&&)
Line
Count
Source
54
8
  inline std::shared_future<void> async(Function &&F, Args &&... ArgList) {
55
8
    auto Task =
56
8
        std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...);
57
8
    return asyncImpl(std::move(Task));
58
8
  }
59
60
  /// Asynchronous submission of a task to the pool. The returned future can be
61
  /// used to wait for the task to finish and is *non-blocking* on destruction.
62
  template <typename Function>
63
  inline std::shared_future<void> async(Function &&F) {
64
    return asyncImpl(std::forward<Function>(F));
65
  }
66
67
  /// Blocking wait for all the threads to complete and the queue to be empty.
68
  /// It is an error to try to add new tasks while blocking on this call.
69
  void wait();
70
71
private:
72
  /// Asynchronous submission of a task to the pool. The returned future can be
73
  /// used to wait for the task to finish and is *non-blocking* on destruction.
74
  std::shared_future<void> asyncImpl(TaskTy F);
75
76
  /// Threads in flight
77
  std::vector<llvm::thread> Threads;
78
79
  /// Tasks waiting for execution in the pool.
80
  std::queue<PackagedTaskTy> Tasks;
81
82
  /// Locking and signaling for accessing the Tasks queue.
83
  std::mutex QueueLock;
84
  std::condition_variable QueueCondition;
85
86
  /// Locking and signaling for job completion
87
  std::mutex CompletionLock;
88
  std::condition_variable CompletionCondition;
89
90
  /// Keep track of the number of thread actually busy
91
  std::atomic<unsigned> ActiveThreads;
92
93
#if LLVM_ENABLE_THREADS // avoids warning for unused variable
94
  /// Signal for the destruction of the pool, asking thread to exit.
95
  bool EnableFlag;
96
#endif
97
};
98
}
99
100
#endif // LLVM_SUPPORT_THREAD_POOL_H