9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADING_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADING_H
13 #include "llvm/ADT/FunctionExtras.h"
14 #include "llvm/ADT/Twine.h"
17 #include <condition_variable>
38 std::condition_variable SlotsChanged;
39 std::size_t FreeSlots;
47 Deadline(std::chrono::steady_clock::time_point Time)
48 : Type(Finite), Time(Time) {}
52 std::chrono::steady_clock::time_point
time()
const {
53 assert(Type == Finite);
57 return (Type == Zero) ||
58 (Type == Finite && Time < std::chrono::steady_clock::now());
61 return (Type == Other.Type) && (Type != Finite || Time == Other.Time);
65 enum Type { Zero, Infinite, Finite };
69 std::chrono::steady_clock::time_point Time;
75 void wait(std::unique_lock<std::mutex> &Lock, std::condition_variable &CV,
78 template <
typename Func>
79 LLVM_NODISCARD
bool wait(std::unique_lock<std::mutex> &Lock,
80 std::condition_variable &CV,
Deadline D, Func F) {
99 bool Notified =
false;
100 mutable std::condition_variable CV;
101 mutable std::mutex Mu;
118 mutable std::mutex Mutex;
119 mutable std::condition_variable TasksReachedZero;
120 std::size_t InFlightTasks = 0;
125 template <
typename T>
147 mutable Container Cache;
148 std::unique_ptr<std::mutex> Mu;
151 Memoize() : Mu(std::make_unique<std::mutex>()) {}
153 template <
typename T,
typename Func>
154 typename Container::mapped_type
get(T &&
Key, Func Compute)
const {
156 std::lock_guard<std::mutex> Lock(*Mu);
157 auto It = Cache.find(
Key);
158 if (It != Cache.end())
164 std::lock_guard<std::mutex> Lock(*Mu);
165 auto R = Cache.try_emplace(std::forward<T>(
Key), V);
168 return R.first->second;
186 using Stopwatch = std::chrono::steady_clock;
187 using Rep = Stopwatch::duration::rep;
190 std::atomic<Rep> Next;
195 : Period(Period.count()),
196 Next((Stopwatch::now() + Delay).time_since_epoch().count()) {}