clang-tools  7.0.0
Threading.h
Go to the documentation of this file.
1 //===--- ThreadPool.h --------------------------------------------*- C++-*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
11 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
12 
13 #include "Context.h"
14 #include "Function.h"
15 #include "llvm/ADT/Twine.h"
16 #include <cassert>
17 #include <condition_variable>
18 #include <memory>
19 #include <mutex>
20 #include <vector>
21 
22 namespace clang {
23 namespace clangd {
24 
25 /// A threadsafe flag that is initially clear.
26 class Notification {
27 public:
28  // Sets the flag. No-op if already set.
29  void notify();
30  // Blocks until flag is set.
31  void wait() const;
32 
33 private:
34  bool Notified = false;
35  mutable std::condition_variable CV;
36  mutable std::mutex Mu;
37 };
38 
39 /// Limits the number of threads that can acquire the lock at the same time.
40 class Semaphore {
41 public:
42  Semaphore(std::size_t MaxLocks);
43 
44  void lock();
45  void unlock();
46 
47 private:
48  std::mutex Mutex;
49  std::condition_variable SlotsChanged;
50  std::size_t FreeSlots;
51 };
52 
53 /// A point in time we can wait for.
54 /// Can be zero (don't wait) or infinity (wait forever).
55 /// (Not time_point::max(), because many std::chrono implementations overflow).
56 class Deadline {
57 public:
58  Deadline(std::chrono::steady_clock::time_point Time)
59  : Type(Finite), Time(Time) {}
60  static Deadline zero() { return Deadline(Zero); }
61  static Deadline infinity() { return Deadline(Infinite); }
62 
63  std::chrono::steady_clock::time_point time() const {
64  assert(Type == Finite);
65  return Time;
66  }
67  bool expired() const {
68  return (Type == Zero) ||
69  (Type == Finite && Time < std::chrono::steady_clock::now());
70  }
71  bool operator==(const Deadline &Other) const {
72  return (Type == Other.Type) && (Type != Finite || Time == Other.Time);
73  }
74 
75 private:
76  enum Type { Zero, Infinite, Finite };
77 
78  Deadline(enum Type Type) : Type(Type) {}
79  enum Type Type;
80  std::chrono::steady_clock::time_point Time;
81 };
82 
83 /// Makes a deadline from a timeout in seconds. None means wait forever.
84 Deadline timeoutSeconds(llvm::Optional<double> Seconds);
85 /// Wait once on CV for the specified duration.
86 void wait(std::unique_lock<std::mutex> &Lock, std::condition_variable &CV,
87  Deadline D);
88 /// Waits on a condition variable until F() is true or D expires.
89 template <typename Func>
90 LLVM_NODISCARD bool wait(std::unique_lock<std::mutex> &Lock,
91  std::condition_variable &CV, Deadline D, Func F) {
92  while (!F()) {
93  if (D.expired())
94  return false;
95  wait(Lock, CV, D);
96  }
97  return true;
98 }
99 
100 /// Runs tasks on separate (detached) threads and wait for all tasks to finish.
101 /// Objects that need to spawn threads can own an AsyncTaskRunner to ensure they
102 /// all complete on destruction.
104 public:
105  /// Destructor waits for all pending tasks to finish.
106  ~AsyncTaskRunner();
107 
108  void wait() const { (void)wait(Deadline::infinity()); }
109  LLVM_NODISCARD bool wait(Deadline D) const;
110  // The name is used for tracing and debugging (e.g. to name a spawned thread).
111  void runAsync(const llvm::Twine &Name, llvm::unique_function<void()> Action);
112 
113 private:
114  mutable std::mutex Mutex;
115  mutable std::condition_variable TasksReachedZero;
116  std::size_t InFlightTasks = 0;
117 };
118 } // namespace clangd
119 } // namespace clang
120 #endif
llvm::StringRef Name
A threadsafe flag that is initially clear.
Definition: Threading.h:26
bool operator==(const Deadline &Other) const
Definition: Threading.h:71
Limits the number of threads that can acquire the lock at the same time.
Definition: Threading.h:40
static Deadline infinity()
Definition: Threading.h:61
llvm::unique_function< void()> Action
Runs tasks on separate (detached) threads and wait for all tasks to finish.
Definition: Threading.h:103
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static Deadline zero()
Definition: Threading.h:60
Deadline timeoutSeconds(llvm::Optional< double > Seconds)
Makes a deadline from a timeout in seconds. None means wait forever.
Definition: Threading.cpp:82
Deadline(std::chrono::steady_clock::time_point Time)
Definition: Threading.h:58
A point in time we can wait for.
Definition: Threading.h:56
bool expired() const
Definition: Threading.h:67
std::chrono::steady_clock::time_point time() const
Definition: Threading.h:63