clang-tools  9.0.0
Threading.h
Go to the documentation of this file.
1 //===--- ThreadPool.h --------------------------------------------*- 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 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
11 
12 #include "Context.h"
13 #include "Function.h"
14 #include "llvm/ADT/Twine.h"
15 #include <cassert>
16 #include <condition_variable>
17 #include <memory>
18 #include <mutex>
19 #include <thread>
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  bool try_lock();
45  void lock();
46  void unlock();
47 
48 private:
49  std::mutex Mutex;
50  std::condition_variable SlotsChanged;
51  std::size_t FreeSlots;
52 };
53 
54 /// A point in time we can wait for.
55 /// Can be zero (don't wait) or infinity (wait forever).
56 /// (Not time_point::max(), because many std::chrono implementations overflow).
57 class Deadline {
58 public:
59  Deadline(std::chrono::steady_clock::time_point Time)
60  : Type(Finite), Time(Time) {}
61  static Deadline zero() { return Deadline(Zero); }
62  static Deadline infinity() { return Deadline(Infinite); }
63 
64  std::chrono::steady_clock::time_point time() const {
65  assert(Type == Finite);
66  return Time;
67  }
68  bool expired() const {
69  return (Type == Zero) ||
70  (Type == Finite && Time < std::chrono::steady_clock::now());
71  }
72  bool operator==(const Deadline &Other) const {
73  return (Type == Other.Type) && (Type != Finite || Time == Other.Time);
74  }
75 
76 private:
77  enum Type { Zero, Infinite, Finite };
78 
79  Deadline(enum Type Type) : Type(Type) {}
80  enum Type Type;
81  std::chrono::steady_clock::time_point Time;
82 };
83 
84 /// Makes a deadline from a timeout in seconds. None means wait forever.
85 Deadline timeoutSeconds(llvm::Optional<double> Seconds);
86 /// Wait once on CV for the specified duration.
87 void wait(std::unique_lock<std::mutex> &Lock, std::condition_variable &CV,
88  Deadline D);
89 /// Waits on a condition variable until F() is true or D expires.
90 template <typename Func>
91 LLVM_NODISCARD bool wait(std::unique_lock<std::mutex> &Lock,
92  std::condition_variable &CV, Deadline D, Func F) {
93  while (!F()) {
94  if (D.expired())
95  return false;
96  wait(Lock, CV, D);
97  }
98  return true;
99 }
100 
101 /// Runs tasks on separate (detached) threads and wait for all tasks to finish.
102 /// Objects that need to spawn threads can own an AsyncTaskRunner to ensure they
103 /// all complete on destruction.
105 public:
106  /// Destructor waits for all pending tasks to finish.
107  ~AsyncTaskRunner();
108 
109  void wait() const { (void)wait(Deadline::infinity()); }
110  LLVM_NODISCARD bool wait(Deadline D) const;
111  // The name is used for tracing and debugging (e.g. to name a spawned thread).
112  void runAsync(const llvm::Twine &Name, llvm::unique_function<void()> Action);
113 
114 private:
115  mutable std::mutex Mutex;
116  mutable std::condition_variable TasksReachedZero;
117  std::size_t InFlightTasks = 0;
118 };
119 
120 } // namespace clangd
121 } // namespace clang
122 #endif
A threadsafe flag that is initially clear.
Definition: Threading.h:26
bool operator==(const Deadline &Other) const
Definition: Threading.h:72
Limits the number of threads that can acquire the lock at the same time.
Definition: Threading.h:40
std::future< T > runAsync(llvm::unique_function< T()> Action)
Runs Action asynchronously with a new std::thread.
Definition: TUScheduler.h:244
static Deadline infinity()
Definition: Threading.h:62
llvm::unique_function< void()> Action
static constexpr llvm::StringLiteral Name
const Decl * D
Definition: XRefs.cpp:868
Runs tasks on separate (detached) threads and wait for all tasks to finish.
Definition: Threading.h:104
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static Deadline zero()
Definition: Threading.h:61
Deadline timeoutSeconds(llvm::Optional< double > Seconds)
Makes a deadline from a timeout in seconds. None means wait forever.
Definition: Threading.cpp:99
Deadline(std::chrono::steady_clock::time_point Time)
Definition: Threading.h:59
A point in time we can wait for.
Definition: Threading.h:57
bool expired() const
Definition: Threading.h:68
std::chrono::steady_clock::time_point time() const
Definition: Threading.h:64
NodeType Type