xref: /llvm-project/clang-tools-extra/clangd/TUScheduler.cpp (revision f59b600c21add076d6a876f29f94990b24b8e321)
1 //===--- TUScheduler.cpp -----------------------------------------*-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 // TUScheduler manages a worker per active file. This ASTWorker processes
9 // updates (modifications to file contents) and reads (actions performed on
10 // preamble/AST) to the file.
11 //
12 // Each ASTWorker owns a dedicated thread to process updates and reads to the
13 // relevant file. Any request gets queued in FIFO order to be processed by that
14 // thread.
15 //
16 // An update request replaces current praser inputs to ensure any subsequent
17 // read sees the version of the file they were requested. It will also issue a
18 // build for new inputs.
19 //
20 // ASTWorker processes the file in two parts, a preamble and a main-file
21 // section. A preamble can be reused between multiple versions of the file until
22 // invalidated by a modification to a header, compile commands or modification
23 // to relevant part of the current file. Such a preamble is called compatible.
24 // An update is considered dead if no read was issued for that version and
25 // diagnostics weren't requested by client or could be generated for a later
26 // version of the file. ASTWorker eliminates such requests as they are
27 // redundant.
28 //
29 // In the presence of stale (non-compatible) preambles, ASTWorker won't publish
30 // diagnostics for update requests. Read requests will be served with ASTs build
31 // with stale preambles, unless the read is picky and requires a compatible
32 // preamble. In such cases it will block until new preamble is built.
33 //
34 // ASTWorker owns a PreambleThread for building preambles. If the preamble gets
35 // invalidated by an update request, a new build will be requested on
36 // PreambleThread. Since PreambleThread only receives requests for newer
37 // versions of the file, in case of multiple requests it will only build the
38 // last one and skip requests in between. Unless client force requested
39 // diagnostics(WantDiagnostics::Yes).
40 //
41 // When a new preamble is built, a "golden" AST is immediately built from that
42 // version of the file. This ensures diagnostics get updated even if the queue
43 // is full.
44 //
45 // Some read requests might just need preamble. Since preambles can be read
46 // concurrently, ASTWorker runs these requests on their own thread. These
47 // requests will receive latest build preamble, which might possibly be stale.
48 
49 #include "TUScheduler.h"
50 #include "CompileCommands.h"
51 #include "Compiler.h"
52 #include "Config.h"
53 #include "Diagnostics.h"
54 #include "GlobalCompilationDatabase.h"
55 #include "ParsedAST.h"
56 #include "Preamble.h"
57 #include "clang-include-cleaner/Record.h"
58 #include "support/Cancellation.h"
59 #include "support/Context.h"
60 #include "support/Logger.h"
61 #include "support/MemoryTree.h"
62 #include "support/Path.h"
63 #include "support/ThreadCrashReporter.h"
64 #include "support/Threading.h"
65 #include "support/Trace.h"
66 #include "clang/Basic/Stack.h"
67 #include "clang/Frontend/CompilerInvocation.h"
68 #include "clang/Tooling/CompilationDatabase.h"
69 #include "llvm/ADT/FunctionExtras.h"
70 #include "llvm/ADT/STLExtras.h"
71 #include "llvm/ADT/ScopeExit.h"
72 #include "llvm/ADT/SmallVector.h"
73 #include "llvm/ADT/StringExtras.h"
74 #include "llvm/ADT/StringRef.h"
75 #include "llvm/Support/Allocator.h"
76 #include "llvm/Support/Errc.h"
77 #include "llvm/Support/ErrorHandling.h"
78 #include "llvm/Support/FormatVariadic.h"
79 #include "llvm/Support/Path.h"
80 #include "llvm/Support/Threading.h"
81 #include "llvm/Support/raw_ostream.h"
82 #include <algorithm>
83 #include <atomic>
84 #include <chrono>
85 #include <condition_variable>
86 #include <functional>
87 #include <memory>
88 #include <mutex>
89 #include <optional>
90 #include <queue>
91 #include <string>
92 #include <thread>
93 #include <type_traits>
94 #include <utility>
95 #include <vector>
96 
97 namespace clang {
98 namespace clangd {
99 using std::chrono::steady_clock;
100 
101 namespace {
102 // Tracks latency (in seconds) of FS operations done during a preamble build.
103 // build_type allows to split by expected VFS cache state (cold on first
104 // preamble, somewhat warm after that when building first preamble for new file,
105 // likely ~everything cached on preamble rebuild.
106 constexpr trace::Metric
107     PreambleBuildFilesystemLatency("preamble_fs_latency",
108                                    trace::Metric::Distribution, "build_type");
109 // Tracks latency of FS operations done during a preamble build as a ratio of
110 // preamble build time. build_type is same as above.
111 constexpr trace::Metric PreambleBuildFilesystemLatencyRatio(
112     "preamble_fs_latency_ratio", trace::Metric::Distribution, "build_type");
113 
114 constexpr trace::Metric PreambleBuildSize("preamble_build_size",
115                                           trace::Metric::Distribution);
116 constexpr trace::Metric PreambleSerializedSize("preamble_serialized_size",
117                                                trace::Metric::Distribution);
118 
119 void reportPreambleBuild(const PreambleBuildStats &Stats,
120                          bool IsFirstPreamble) {
121   auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
122     PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
123     if (Stats.TotalBuildTime > 0) // Avoid division by zero.
124       PreambleBuildFilesystemLatencyRatio.record(
125           Stats.FileSystemTime / Stats.TotalBuildTime, Label);
126   };
127 
128   static llvm::once_flag OnceFlag;
129   llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
130   RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
131 
132   PreambleBuildSize.record(Stats.BuildSize);
133   PreambleSerializedSize.record(Stats.SerializedSize);
134 }
135 
136 class ASTWorker;
137 } // namespace
138 
139 static clang::clangd::Key<std::string> FileBeingProcessed;
140 
141 std::optional<llvm::StringRef> TUScheduler::getFileBeingProcessedInContext() {
142   if (auto *File = Context::current().get(FileBeingProcessed))
143     return llvm::StringRef(*File);
144   return std::nullopt;
145 }
146 
147 /// An LRU cache of idle ASTs.
148 /// Because we want to limit the overall number of these we retain, the cache
149 /// owns ASTs (and may evict them) while their workers are idle.
150 /// Workers borrow ASTs when active, and return them when done.
151 class TUScheduler::ASTCache {
152 public:
153   using Key = const ASTWorker *;
154 
155   ASTCache(unsigned MaxRetainedASTs) : MaxRetainedASTs(MaxRetainedASTs) {}
156 
157   /// Returns result of getUsedBytes() for the AST cached by \p K.
158   /// If no AST is cached, 0 is returned.
159   std::size_t getUsedBytes(Key K) {
160     std::lock_guard<std::mutex> Lock(Mut);
161     auto It = findByKey(K);
162     if (It == LRU.end() || !It->second)
163       return 0;
164     return It->second->getUsedBytes();
165   }
166 
167   /// Store the value in the pool, possibly removing the last used AST.
168   /// The value should not be in the pool when this function is called.
169   void put(Key K, std::unique_ptr<ParsedAST> V) {
170     std::unique_lock<std::mutex> Lock(Mut);
171     assert(findByKey(K) == LRU.end());
172 
173     LRU.insert(LRU.begin(), {K, std::move(V)});
174     if (LRU.size() <= MaxRetainedASTs)
175       return;
176     // We're past the limit, remove the last element.
177     std::unique_ptr<ParsedAST> ForCleanup = std::move(LRU.back().second);
178     LRU.pop_back();
179     // Run the expensive destructor outside the lock.
180     Lock.unlock();
181     ForCleanup.reset();
182   }
183 
184   /// Returns the cached value for \p K, or std::nullopt if the value is not in
185   /// the cache anymore. If nullptr was cached for \p K, this function will
186   /// return a null unique_ptr wrapped into an optional.
187   /// If \p AccessMetric is set records whether there was a hit or miss.
188   std::optional<std::unique_ptr<ParsedAST>>
189   take(Key K, const trace::Metric *AccessMetric = nullptr) {
190     // Record metric after unlocking the mutex.
191     std::unique_lock<std::mutex> Lock(Mut);
192     auto Existing = findByKey(K);
193     if (Existing == LRU.end()) {
194       if (AccessMetric)
195         AccessMetric->record(1, "miss");
196       return std::nullopt;
197     }
198     if (AccessMetric)
199       AccessMetric->record(1, "hit");
200     std::unique_ptr<ParsedAST> V = std::move(Existing->second);
201     LRU.erase(Existing);
202     // GCC 4.8 fails to compile `return V;`, as it tries to call the copy
203     // constructor of unique_ptr, so we call the move ctor explicitly to avoid
204     // this miscompile.
205     return std::optional<std::unique_ptr<ParsedAST>>(std::move(V));
206   }
207 
208 private:
209   using KVPair = std::pair<Key, std::unique_ptr<ParsedAST>>;
210 
211   std::vector<KVPair>::iterator findByKey(Key K) {
212     return llvm::find_if(LRU, [K](const KVPair &P) { return P.first == K; });
213   }
214 
215   std::mutex Mut;
216   unsigned MaxRetainedASTs;
217   /// Items sorted in LRU order, i.e. first item is the most recently accessed
218   /// one.
219   std::vector<KVPair> LRU; /* GUARDED_BY(Mut) */
220 };
221 
222 /// A map from header files to an opened "proxy" file that includes them.
223 /// If you open the header, the compile command from the proxy file is used.
224 ///
225 /// This inclusion information could also naturally live in the index, but there
226 /// are advantages to using open files instead:
227 ///  - it's easier to achieve a *stable* choice of proxy, which is important
228 ///    to avoid invalidating the preamble
229 ///  - context-sensitive flags for libraries with multiple configurations
230 ///    (e.g. C++ stdlib sensitivity to -std version)
231 ///  - predictable behavior, e.g. guarantees that go-to-def landing on a header
232 ///    will have a suitable command available
233 ///  - fewer scaling problems to solve (project include graphs are big!)
234 ///
235 /// Implementation details:
236 /// - We only record this for mainfiles where the command was trustworthy
237 ///   (i.e. not inferred). This avoids a bad inference "infecting" other files.
238 /// - Once we've picked a proxy file for a header, we stick with it until the
239 ///   proxy file is invalidated *and* a new candidate proxy file is built.
240 ///   Switching proxies is expensive, as the compile flags will (probably)
241 ///   change and therefore we'll end up rebuilding the header's preamble.
242 /// - We don't capture the actual compile command, but just the filename we
243 ///   should query to get it. This avoids getting out of sync with the CDB.
244 ///
245 /// All methods are threadsafe. In practice, update() comes from preamble
246 /// threads, remove()s mostly from the main thread, and get() from ASTWorker.
247 /// Writes are rare and reads are cheap, so we don't expect much contention.
248 class TUScheduler::HeaderIncluderCache {
249   // We should be a little careful how we store the include graph of open
250   // files, as each can have a large number of transitive headers.
251   // This representation is O(unique transitive source files).
252   llvm::BumpPtrAllocator Arena;
253   struct Association {
254     llvm::StringRef MainFile;
255     // Circular-linked-list of associations with the same mainFile.
256     // Null indicates that the mainfile was removed.
257     Association *Next;
258   };
259   llvm::StringMap<Association, llvm::BumpPtrAllocator &> HeaderToMain;
260   llvm::StringMap<Association *, llvm::BumpPtrAllocator &> MainToFirst;
261   std::atomic<size_t> UsedBytes; // Updated after writes.
262   mutable std::mutex Mu;
263 
264   void invalidate(Association *First) {
265     Association *Current = First;
266     do {
267       Association *Next = Current->Next;
268       Current->Next = nullptr;
269       Current = Next;
270     } while (Current != First);
271   }
272 
273   // Create the circular list and return the head of it.
274   Association *associate(llvm::StringRef MainFile,
275                          llvm::ArrayRef<std::string> Headers) {
276     Association *First = nullptr, *Prev = nullptr;
277     for (const std::string &Header : Headers) {
278       auto &Assoc = HeaderToMain[Header];
279       if (Assoc.Next)
280         continue; // Already has a valid association.
281 
282       Assoc.MainFile = MainFile;
283       Assoc.Next = Prev;
284       Prev = &Assoc;
285       if (!First)
286         First = &Assoc;
287     }
288     if (First)
289       First->Next = Prev;
290     return First;
291   }
292 
293   void updateMemoryUsage() {
294     auto StringMapHeap = [](const auto &Map) {
295       // StringMap stores the hashtable on the heap.
296       // It contains pointers to the entries, and a hashcode for each.
297       return Map.getNumBuckets() * (sizeof(void *) + sizeof(unsigned));
298     };
299     size_t Usage = Arena.getTotalMemory() + StringMapHeap(MainToFirst) +
300                    StringMapHeap(HeaderToMain) + sizeof(*this);
301     UsedBytes.store(Usage, std::memory_order_release);
302   }
303 
304 public:
305   HeaderIncluderCache() : HeaderToMain(Arena), MainToFirst(Arena) {
306     updateMemoryUsage();
307   }
308 
309   // Associate each header with MainFile (unless already associated).
310   // Headers not in the list will have their associations removed.
311   void update(PathRef MainFile, llvm::ArrayRef<std::string> Headers) {
312     std::lock_guard<std::mutex> Lock(Mu);
313     auto It = MainToFirst.try_emplace(MainFile, nullptr);
314     Association *&First = It.first->second;
315     if (First)
316       invalidate(First);
317     First = associate(It.first->first(), Headers);
318     updateMemoryUsage();
319   }
320 
321   // Mark MainFile as gone.
322   // This will *not* disassociate headers with MainFile immediately, but they
323   // will be eligible for association with other files that get update()d.
324   void remove(PathRef MainFile) {
325     std::lock_guard<std::mutex> Lock(Mu);
326     Association *&First = MainToFirst[MainFile];
327     if (First) {
328       invalidate(First);
329       First = nullptr;
330     }
331     // MainToFirst entry should stay alive, as Associations might be pointing at
332     // its key.
333   }
334 
335   /// Get the mainfile associated with Header, or the empty string if none.
336   std::string get(PathRef Header) const {
337     std::lock_guard<std::mutex> Lock(Mu);
338     return HeaderToMain.lookup(Header).MainFile.str();
339   }
340 
341   size_t getUsedBytes() const {
342     return UsedBytes.load(std::memory_order_acquire);
343   }
344 };
345 
346 namespace {
347 
348 bool isReliable(const tooling::CompileCommand &Cmd) {
349   return Cmd.Heuristic.empty();
350 }
351 
352 /// Threadsafe manager for updating a TUStatus and emitting it after each
353 /// update.
354 class SynchronizedTUStatus {
355 public:
356   SynchronizedTUStatus(PathRef FileName, ParsingCallbacks &Callbacks)
357       : FileName(FileName), Callbacks(Callbacks) {}
358 
359   void update(llvm::function_ref<void(TUStatus &)> Mutator) {
360     std::lock_guard<std::mutex> Lock(StatusMu);
361     Mutator(Status);
362     emitStatusLocked();
363   }
364 
365   /// Prevents emitting of further updates.
366   void stop() {
367     std::lock_guard<std::mutex> Lock(StatusMu);
368     CanPublish = false;
369   }
370 
371 private:
372   void emitStatusLocked() {
373     if (CanPublish)
374       Callbacks.onFileUpdated(FileName, Status);
375   }
376 
377   const Path FileName;
378 
379   std::mutex StatusMu;
380   TUStatus Status;
381   bool CanPublish = true;
382   ParsingCallbacks &Callbacks;
383 };
384 
385 // An attempt to acquire resources for a task using PreambleThrottler.
386 // Initially it is unsatisfied, it (hopefully) becomes satisfied later but may
387 // be destroyed before then. Destruction releases all resources.
388 class PreambleThrottlerRequest {
389 public:
390   // The condition variable is signalled when the request is satisfied.
391   PreambleThrottlerRequest(llvm::StringRef Filename,
392                            PreambleThrottler *Throttler,
393                            std::condition_variable &CV)
394       : Throttler(Throttler),
395         Satisfied(Throttler == nullptr) {
396     // If there is no throttler, this dummy request is always satisfied.
397     if (!Throttler)
398       return;
399     ID = Throttler->acquire(Filename, [&] {
400       Satisfied.store(true, std::memory_order_release);
401       CV.notify_all();
402     });
403   }
404 
405   bool satisfied() const { return Satisfied.load(std::memory_order_acquire); }
406 
407   // When the request is destroyed:
408   //  - if resources are not yet obtained, stop trying to get them.
409   //  - if resources were obtained, release them.
410   ~PreambleThrottlerRequest() {
411     if (Throttler)
412       Throttler->release(ID);
413   }
414   PreambleThrottlerRequest(const PreambleThrottlerRequest &) = delete;
415   PreambleThrottlerRequest &
416   operator=(const PreambleThrottlerRequest &) = delete;
417 
418 private:
419   PreambleThrottler::RequestID ID;
420   PreambleThrottler *Throttler;
421   std::atomic<bool> Satisfied = {false};
422 };
423 
424 /// Responsible for building preambles. Whenever the thread is idle and the
425 /// preamble is outdated, it starts to build a fresh preamble from the latest
426 /// inputs. If RunSync is true, preambles are built synchronously in update()
427 /// instead.
428 class PreambleThread {
429 public:
430   PreambleThread(llvm::StringRef FileName, ParsingCallbacks &Callbacks,
431                  bool StorePreambleInMemory, bool RunSync,
432                  PreambleThrottler *Throttler, SynchronizedTUStatus &Status,
433                  TUScheduler::HeaderIncluderCache &HeaderIncluders,
434                  ASTWorker &AW)
435       : FileName(FileName), Callbacks(Callbacks),
436         StoreInMemory(StorePreambleInMemory), RunSync(RunSync),
437         Throttler(Throttler), Status(Status), ASTPeer(AW),
438         HeaderIncluders(HeaderIncluders) {}
439 
440   /// It isn't guaranteed that each requested version will be built. If there
441   /// are multiple update requests while building a preamble, only the last one
442   /// will be built.
443   void update(std::unique_ptr<CompilerInvocation> CI, ParseInputs PI,
444               std::vector<Diag> CIDiags, WantDiagnostics WantDiags) {
445     Request Req = {std::move(CI), std::move(PI), std::move(CIDiags), WantDiags,
446                    Context::current().clone()};
447     if (RunSync) {
448       build(std::move(Req));
449       Status.update([](TUStatus &Status) {
450         Status.PreambleActivity = PreambleAction::Idle;
451       });
452       return;
453     }
454     {
455       std::unique_lock<std::mutex> Lock(Mutex);
456       // If NextReq was requested with WantDiagnostics::Yes we cannot just drop
457       // that on the floor. Block until we start building it. This won't
458       // dead-lock as we are blocking the caller thread, while builds continue
459       // on preamble thread.
460       ReqCV.wait(Lock, [this] {
461         return !NextReq || NextReq->WantDiags != WantDiagnostics::Yes;
462       });
463       NextReq = std::move(Req);
464     }
465     // Let the worker thread know there's a request, notify_one is safe as there
466     // should be a single worker thread waiting on it.
467     ReqCV.notify_all();
468   }
469 
470   void run() {
471     // We mark the current as the stack bottom so that clang running on this
472     // thread can notice the stack usage and prevent stack overflow with best
473     // efforts. Same applies to other calls thoughout clangd.
474     clang::noteBottomOfStack();
475     while (true) {
476       std::optional<PreambleThrottlerRequest> Throttle;
477       {
478         std::unique_lock<std::mutex> Lock(Mutex);
479         assert(!CurrentReq && "Already processing a request?");
480         // Wait until stop is called or there is a request.
481         ReqCV.wait(Lock, [&] { return NextReq || Done; });
482         if (Done)
483           break;
484 
485         {
486           Throttle.emplace(FileName, Throttler, ReqCV);
487           std::optional<trace::Span> Tracer;
488           // If acquire succeeded synchronously, avoid status jitter.
489           if (!Throttle->satisfied()) {
490             Tracer.emplace("PreambleThrottle");
491             Status.update([&](TUStatus &Status) {
492               Status.PreambleActivity = PreambleAction::Queued;
493             });
494           }
495           ReqCV.wait(Lock, [&] { return Throttle->satisfied() || Done; });
496         }
497         if (Done)
498           break;
499         // While waiting for the throttler, the request may have been updated!
500         // That's fine though, there's still guaranteed to be some request.
501 
502         CurrentReq = std::move(*NextReq);
503         NextReq.reset();
504       }
505 
506       {
507         WithContext Guard(std::move(CurrentReq->Ctx));
508         // Note that we don't make use of the ContextProvider here.
509         // Preamble tasks are always scheduled by ASTWorker tasks, and we
510         // reuse the context/config that was created at that level.
511 
512         // Build the preamble and let the waiters know about it.
513         build(std::move(*CurrentReq));
514       }
515       // Releasing the throttle before destroying the request assists testing.
516       Throttle.reset();
517       bool IsEmpty = false;
518       {
519         std::lock_guard<std::mutex> Lock(Mutex);
520         CurrentReq.reset();
521         IsEmpty = !NextReq;
522       }
523       if (IsEmpty) {
524         // We don't perform this above, before waiting for a request to make
525         // tests more deterministic. As there can be a race between this thread
526         // and client thread(clangdserver).
527         Status.update([](TUStatus &Status) {
528           Status.PreambleActivity = PreambleAction::Idle;
529         });
530       }
531       ReqCV.notify_all();
532     }
533     dlog("Preamble worker for {0} stopped", FileName);
534   }
535 
536   /// Signals the run loop to exit.
537   void stop() {
538     dlog("Preamble worker for {0} received stop", FileName);
539     {
540       std::lock_guard<std::mutex> Lock(Mutex);
541       Done = true;
542       NextReq.reset();
543     }
544     // Let the worker thread know that it should stop.
545     ReqCV.notify_all();
546   }
547 
548   bool blockUntilIdle(Deadline Timeout) const {
549     std::unique_lock<std::mutex> Lock(Mutex);
550     return wait(Lock, ReqCV, Timeout, [&] { return !NextReq && !CurrentReq; });
551   }
552 
553 private:
554   /// Holds inputs required for building a preamble. CI is guaranteed to be
555   /// non-null.
556   struct Request {
557     std::unique_ptr<CompilerInvocation> CI;
558     ParseInputs Inputs;
559     std::vector<Diag> CIDiags;
560     WantDiagnostics WantDiags;
561     Context Ctx;
562   };
563 
564   bool isDone() {
565     std::lock_guard<std::mutex> Lock(Mutex);
566     return Done;
567   }
568 
569   /// Builds a preamble for \p Req, might reuse LatestBuild if possible.
570   /// Notifies ASTWorker after build finishes.
571   void build(Request Req);
572 
573   mutable std::mutex Mutex;
574   bool Done = false;                  /* GUARDED_BY(Mutex) */
575   std::optional<Request> NextReq;     /* GUARDED_BY(Mutex) */
576   std::optional<Request> CurrentReq;  /* GUARDED_BY(Mutex) */
577   // Signaled whenever a thread populates NextReq or worker thread builds a
578   // Preamble.
579   mutable std::condition_variable ReqCV; /* GUARDED_BY(Mutex) */
580   // Accessed only by preamble thread.
581   std::shared_ptr<const PreambleData> LatestBuild;
582 
583   const Path FileName;
584   ParsingCallbacks &Callbacks;
585   const bool StoreInMemory;
586   const bool RunSync;
587   PreambleThrottler *Throttler;
588 
589   SynchronizedTUStatus &Status;
590   ASTWorker &ASTPeer;
591   TUScheduler::HeaderIncluderCache &HeaderIncluders;
592 };
593 
594 class ASTWorkerHandle;
595 
596 /// Owns one instance of the AST, schedules updates and reads of it.
597 /// Also responsible for building and providing access to the preamble.
598 /// Each ASTWorker processes the async requests sent to it on a separate
599 /// dedicated thread.
600 /// The ASTWorker that manages the AST is shared by both the processing thread
601 /// and the TUScheduler. The TUScheduler should discard an ASTWorker when
602 /// remove() is called, but its thread may be busy and we don't want to block.
603 /// So the workers are accessed via an ASTWorkerHandle. Destroying the handle
604 /// signals the worker to exit its run loop and gives up shared ownership of the
605 /// worker.
606 class ASTWorker {
607   friend class ASTWorkerHandle;
608   ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
609             TUScheduler::ASTCache &LRUCache,
610             TUScheduler::HeaderIncluderCache &HeaderIncluders,
611             Semaphore &Barrier, bool RunSync, const TUScheduler::Options &Opts,
612             ParsingCallbacks &Callbacks);
613 
614 public:
615   /// Create a new ASTWorker and return a handle to it.
616   /// The processing thread is spawned using \p Tasks. However, when \p Tasks
617   /// is null, all requests will be processed on the calling thread
618   /// synchronously instead. \p Barrier is acquired when processing each
619   /// request, it is used to limit the number of actively running threads.
620   static ASTWorkerHandle
621   create(PathRef FileName, const GlobalCompilationDatabase &CDB,
622          TUScheduler::ASTCache &IdleASTs,
623          TUScheduler::HeaderIncluderCache &HeaderIncluders,
624          AsyncTaskRunner *Tasks, Semaphore &Barrier,
625          const TUScheduler::Options &Opts, ParsingCallbacks &Callbacks);
626   ~ASTWorker();
627   ASTWorker(const ASTWorker &other) = delete;
628   ASTWorker &operator=(const ASTWorker &other) = delete;
629   void update(ParseInputs Inputs, WantDiagnostics, bool ContentChanged);
630   void
631   runWithAST(llvm::StringRef Name,
632              llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action,
633              TUScheduler::ASTActionInvalidation);
634   bool blockUntilIdle(Deadline Timeout) const;
635 
636   std::shared_ptr<const PreambleData> getPossiblyStalePreamble(
637       std::shared_ptr<const ASTSignals> *ASTSignals = nullptr) const;
638 
639   /// Used to inform ASTWorker about a new preamble build by PreambleThread.
640   /// Diagnostics are only published through this callback. This ensures they
641   /// are always for newer versions of the file, as the callback gets called in
642   /// the same order as update requests.
643   void updatePreamble(std::unique_ptr<CompilerInvocation> CI, ParseInputs PI,
644                       std::shared_ptr<const PreambleData> Preamble,
645                       std::vector<Diag> CIDiags, WantDiagnostics WantDiags);
646 
647   /// Returns compile command from the current file inputs.
648   tooling::CompileCommand getCurrentCompileCommand() const;
649 
650   /// Wait for the first build of preamble to finish. Preamble itself can be
651   /// accessed via getPossiblyStalePreamble(). Note that this function will
652   /// return after an unsuccessful build of the preamble too, i.e. result of
653   /// getPossiblyStalePreamble() can be null even after this function returns.
654   void waitForFirstPreamble() const;
655 
656   TUScheduler::FileStats stats() const;
657   bool isASTCached() const;
658 
659 private:
660   // Details of an update request that are relevant to scheduling.
661   struct UpdateType {
662     // Do we want diagnostics from this version?
663     // If Yes, we must always build this version.
664     // If No, we only need to build this version if it's read.
665     // If Auto, we build if it's read or if the debounce expires.
666     WantDiagnostics Diagnostics;
667     // Did the main-file content of the document change?
668     // If so, we're allowed to cancel certain invalidated preceding reads.
669     bool ContentChanged;
670   };
671 
672   /// Publishes diagnostics for \p Inputs. It will build an AST or reuse the
673   /// cached one if applicable. Assumes LatestPreamble is compatible for \p
674   /// Inputs.
675   void generateDiagnostics(std::unique_ptr<CompilerInvocation> Invocation,
676                            ParseInputs Inputs, std::vector<Diag> CIDiags);
677 
678   void updateASTSignals(ParsedAST &AST);
679 
680   // Must be called exactly once on processing thread. Will return after
681   // stop() is called on a separate thread and all pending requests are
682   // processed.
683   void run();
684   /// Signal that run() should finish processing pending requests and exit.
685   void stop();
686 
687   /// Adds a new task to the end of the request queue.
688   void startTask(llvm::StringRef Name, llvm::unique_function<void()> Task,
689                  std::optional<UpdateType> Update,
690                  TUScheduler::ASTActionInvalidation);
691   /// Runs a task synchronously.
692   void runTask(llvm::StringRef Name, llvm::function_ref<void()> Task);
693 
694   /// Determines the next action to perform.
695   /// All actions that should never run are discarded.
696   /// Returns a deadline for the next action. If it's expired, run now.
697   /// scheduleLocked() is called again at the deadline, or if requests arrive.
698   Deadline scheduleLocked();
699   /// Should the first task in the queue be skipped instead of run?
700   bool shouldSkipHeadLocked() const;
701 
702   struct Request {
703     llvm::unique_function<void()> Action;
704     std::string Name;
705     steady_clock::time_point AddTime;
706     Context Ctx;
707     std::optional<Context> QueueCtx;
708     std::optional<UpdateType> Update;
709     TUScheduler::ASTActionInvalidation InvalidationPolicy;
710     Canceler Invalidate;
711   };
712 
713   /// Handles retention of ASTs.
714   TUScheduler::ASTCache &IdleASTs;
715   TUScheduler::HeaderIncluderCache &HeaderIncluders;
716   const bool RunSync;
717   /// Time to wait after an update to see whether another update obsoletes it.
718   const DebouncePolicy UpdateDebounce;
719   /// File that ASTWorker is responsible for.
720   const Path FileName;
721   /// Callback to create processing contexts for tasks.
722   const std::function<Context(llvm::StringRef)> ContextProvider;
723   const GlobalCompilationDatabase &CDB;
724   /// Callback invoked when preamble or main file AST is built.
725   ParsingCallbacks &Callbacks;
726 
727   Semaphore &Barrier;
728   /// Whether the 'onMainAST' callback ran for the current FileInputs.
729   bool RanASTCallback = false;
730   /// Guards members used by both TUScheduler and the worker thread.
731   mutable std::mutex Mutex;
732   /// File inputs, currently being used by the worker.
733   /// Writes and reads from unknown threads are locked. Reads from the worker
734   /// thread are not locked, as it's the only writer.
735   ParseInputs FileInputs; /* GUARDED_BY(Mutex) */
736   /// Times of recent AST rebuilds, used for UpdateDebounce computation.
737   llvm::SmallVector<DebouncePolicy::clock::duration>
738       RebuildTimes; /* GUARDED_BY(Mutex) */
739   /// Set to true to signal run() to finish processing.
740   bool Done;                              /* GUARDED_BY(Mutex) */
741   std::deque<Request> Requests;           /* GUARDED_BY(Mutex) */
742   std::optional<Request> CurrentRequest;  /* GUARDED_BY(Mutex) */
743   /// Signalled whenever a new request has been scheduled or processing of a
744   /// request has completed.
745   mutable std::condition_variable RequestsCV;
746   std::shared_ptr<const ASTSignals> LatestASTSignals; /* GUARDED_BY(Mutex) */
747   /// Latest build preamble for current TU.
748   /// std::nullopt means no builds yet, null means there was an error while
749   /// building. Only written by ASTWorker's thread.
750   std::optional<std::shared_ptr<const PreambleData>> LatestPreamble;
751   std::deque<Request> PreambleRequests; /* GUARDED_BY(Mutex) */
752   /// Signaled whenever LatestPreamble changes state or there's a new
753   /// PreambleRequest.
754   mutable std::condition_variable PreambleCV;
755   /// Guards the callback that publishes results of AST-related computations
756   /// (diagnostics) and file statuses.
757   std::mutex PublishMu;
758   // Used to prevent remove document + add document races that lead to
759   // out-of-order callbacks for publishing results of onMainAST callback.
760   //
761   // The lifetime of the old/new ASTWorkers will overlap, but their handles
762   // don't. When the old handle is destroyed, the old worker will stop reporting
763   // any results to the user.
764   bool CanPublishResults = true; /* GUARDED_BY(PublishMu) */
765   std::atomic<unsigned> ASTBuildCount = {0};
766   std::atomic<unsigned> PreambleBuildCount = {0};
767 
768   SynchronizedTUStatus Status;
769   PreambleThread PreamblePeer;
770 };
771 
772 /// A smart-pointer-like class that points to an active ASTWorker.
773 /// In destructor, signals to the underlying ASTWorker that no new requests will
774 /// be sent and the processing loop may exit (after running all pending
775 /// requests).
776 class ASTWorkerHandle {
777   friend class ASTWorker;
778   ASTWorkerHandle(std::shared_ptr<ASTWorker> Worker)
779       : Worker(std::move(Worker)) {
780     assert(this->Worker);
781   }
782 
783 public:
784   ASTWorkerHandle(const ASTWorkerHandle &) = delete;
785   ASTWorkerHandle &operator=(const ASTWorkerHandle &) = delete;
786   ASTWorkerHandle(ASTWorkerHandle &&) = default;
787   ASTWorkerHandle &operator=(ASTWorkerHandle &&) = default;
788 
789   ~ASTWorkerHandle() {
790     if (Worker)
791       Worker->stop();
792   }
793 
794   ASTWorker &operator*() {
795     assert(Worker && "Handle was moved from");
796     return *Worker;
797   }
798 
799   ASTWorker *operator->() {
800     assert(Worker && "Handle was moved from");
801     return Worker.get();
802   }
803 
804   /// Returns an owning reference to the underlying ASTWorker that can outlive
805   /// the ASTWorkerHandle. However, no new requests to an active ASTWorker can
806   /// be schedule via the returned reference, i.e. only reads of the preamble
807   /// are possible.
808   std::shared_ptr<const ASTWorker> lock() { return Worker; }
809 
810 private:
811   std::shared_ptr<ASTWorker> Worker;
812 };
813 
814 ASTWorkerHandle
815 ASTWorker::create(PathRef FileName, const GlobalCompilationDatabase &CDB,
816                   TUScheduler::ASTCache &IdleASTs,
817                   TUScheduler::HeaderIncluderCache &HeaderIncluders,
818                   AsyncTaskRunner *Tasks, Semaphore &Barrier,
819                   const TUScheduler::Options &Opts,
820                   ParsingCallbacks &Callbacks) {
821   std::shared_ptr<ASTWorker> Worker(
822       new ASTWorker(FileName, CDB, IdleASTs, HeaderIncluders, Barrier,
823                     /*RunSync=*/!Tasks, Opts, Callbacks));
824   if (Tasks) {
825     Tasks->runAsync("ASTWorker:" + llvm::sys::path::filename(FileName),
826                     [Worker]() { Worker->run(); });
827     Tasks->runAsync("PreambleWorker:" + llvm::sys::path::filename(FileName),
828                     [Worker]() { Worker->PreamblePeer.run(); });
829   }
830 
831   return ASTWorkerHandle(std::move(Worker));
832 }
833 
834 ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
835                      TUScheduler::ASTCache &LRUCache,
836                      TUScheduler::HeaderIncluderCache &HeaderIncluders,
837                      Semaphore &Barrier, bool RunSync,
838                      const TUScheduler::Options &Opts,
839                      ParsingCallbacks &Callbacks)
840     : IdleASTs(LRUCache), HeaderIncluders(HeaderIncluders), RunSync(RunSync),
841       UpdateDebounce(Opts.UpdateDebounce), FileName(FileName),
842       ContextProvider(Opts.ContextProvider), CDB(CDB), Callbacks(Callbacks),
843       Barrier(Barrier), Done(false), Status(FileName, Callbacks),
844       PreamblePeer(FileName, Callbacks, Opts.StorePreamblesInMemory, RunSync,
845                    Opts.PreambleThrottler, Status, HeaderIncluders, *this) {
846   // Set a fallback command because compile command can be accessed before
847   // `Inputs` is initialized. Other fields are only used after initialization
848   // from client inputs.
849   FileInputs.CompileCommand = CDB.getFallbackCommand(FileName);
850 }
851 
852 ASTWorker::~ASTWorker() {
853   // Make sure we remove the cached AST, if any.
854   IdleASTs.take(this);
855 #ifndef NDEBUG
856   std::lock_guard<std::mutex> Lock(Mutex);
857   assert(Done && "handle was not destroyed");
858   assert(Requests.empty() && !CurrentRequest &&
859          "unprocessed requests when destroying ASTWorker");
860 #endif
861 }
862 
863 void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags,
864                        bool ContentChanged) {
865   llvm::StringLiteral TaskName = "Update";
866   auto Task = [=]() mutable {
867     // Get the actual command as `Inputs` does not have a command.
868     // FIXME: some build systems like Bazel will take time to preparing
869     // environment to build the file, it would be nice if we could emit a
870     // "PreparingBuild" status to inform users, it is non-trivial given the
871     // current implementation.
872     auto Cmd = CDB.getCompileCommand(FileName);
873     // If we don't have a reliable command for this file, it may be a header.
874     // Try to find a file that includes it, to borrow its command.
875     if (!Cmd || !isReliable(*Cmd)) {
876       std::string ProxyFile = HeaderIncluders.get(FileName);
877       if (!ProxyFile.empty()) {
878         auto ProxyCmd = CDB.getCompileCommand(ProxyFile);
879         if (!ProxyCmd || !isReliable(*ProxyCmd)) {
880           // This command is supposed to be reliable! It's probably gone.
881           HeaderIncluders.remove(ProxyFile);
882         } else {
883           // We have a reliable command for an including file, use it.
884           Cmd = tooling::transferCompileCommand(std::move(*ProxyCmd), FileName);
885         }
886       }
887     }
888     if (Cmd)
889       Inputs.CompileCommand = std::move(*Cmd);
890     else
891       Inputs.CompileCommand = CDB.getFallbackCommand(FileName);
892 
893     bool InputsAreTheSame =
894         std::tie(FileInputs.CompileCommand, FileInputs.Contents) ==
895         std::tie(Inputs.CompileCommand, Inputs.Contents);
896     // Cached AST is invalidated.
897     if (!InputsAreTheSame) {
898       IdleASTs.take(this);
899       RanASTCallback = false;
900     }
901 
902     // Update current inputs so that subsequent reads can see them.
903     {
904       std::lock_guard<std::mutex> Lock(Mutex);
905       FileInputs = Inputs;
906     }
907 
908     log("ASTWorker building file {0} version {1} with command {2}\n[{3}]\n{4}",
909         FileName, Inputs.Version, Inputs.CompileCommand.Heuristic,
910         Inputs.CompileCommand.Directory,
911         printArgv(Inputs.CompileCommand.CommandLine));
912 
913     StoreDiags CompilerInvocationDiagConsumer;
914     std::vector<std::string> CC1Args;
915     std::unique_ptr<CompilerInvocation> Invocation = buildCompilerInvocation(
916         Inputs, CompilerInvocationDiagConsumer, &CC1Args);
917     // Log cc1 args even (especially!) if creating invocation failed.
918     if (!CC1Args.empty())
919       vlog("Driver produced command: cc1 {0}", printArgv(CC1Args));
920     std::vector<Diag> CompilerInvocationDiags =
921         CompilerInvocationDiagConsumer.take();
922     if (!Invocation) {
923       elog("Could not build CompilerInvocation for file {0}", FileName);
924       // Remove the old AST if it's still in cache.
925       IdleASTs.take(this);
926       RanASTCallback = false;
927       // Report the diagnostics we collected when parsing the command line.
928       Callbacks.onFailedAST(FileName, Inputs.Version,
929                             std::move(CompilerInvocationDiags),
930                             [&](llvm::function_ref<void()> Publish) {
931                               // Ensure we only publish results from the worker
932                               // if the file was not removed, making sure there
933                               // are not race conditions.
934                               std::lock_guard<std::mutex> Lock(PublishMu);
935                               if (CanPublishResults)
936                                 Publish();
937                             });
938       // Note that this might throw away a stale preamble that might still be
939       // useful, but this is how we communicate a build error.
940       LatestPreamble.emplace();
941       // Make sure anyone waiting for the preamble gets notified it could not be
942       // built.
943       PreambleCV.notify_all();
944       return;
945     }
946 
947     // Inform preamble peer, before attempting to build diagnostics so that they
948     // can be built concurrently.
949     PreamblePeer.update(std::make_unique<CompilerInvocation>(*Invocation),
950                         Inputs, CompilerInvocationDiags, WantDiags);
951 
952     // Emit diagnostics from (possibly) stale preamble while waiting for a
953     // rebuild. Newly built preamble cannot emit diagnostics before this call
954     // finishes (ast callbacks are called from astpeer thread), hence we
955     // guarantee eventual consistency.
956     if (LatestPreamble && WantDiags != WantDiagnostics::No)
957       generateDiagnostics(std::move(Invocation), std::move(Inputs),
958                           std::move(CompilerInvocationDiags));
959 
960     std::unique_lock<std::mutex> Lock(Mutex);
961     PreambleCV.wait(Lock, [this] {
962       // Block until we reiceve a preamble request, unless a preamble already
963       // exists, as patching an empty preamble would imply rebuilding it from
964       // scratch.
965       // We block here instead of the consumer to prevent any deadlocks. Since
966       // LatestPreamble is only populated by ASTWorker thread.
967       return LatestPreamble || !PreambleRequests.empty() || Done;
968     });
969   };
970   startTask(TaskName, std::move(Task), UpdateType{WantDiags, ContentChanged},
971             TUScheduler::NoInvalidation);
972 }
973 
974 void ASTWorker::runWithAST(
975     llvm::StringRef Name,
976     llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action,
977     TUScheduler::ASTActionInvalidation Invalidation) {
978   // Tracks ast cache accesses for read operations.
979   static constexpr trace::Metric ASTAccessForRead(
980       "ast_access_read", trace::Metric::Counter, "result");
981   auto Task = [=, Action = std::move(Action)]() mutable {
982     if (auto Reason = isCancelled())
983       return Action(llvm::make_error<CancelledError>(Reason));
984     std::optional<std::unique_ptr<ParsedAST>> AST =
985         IdleASTs.take(this, &ASTAccessForRead);
986     if (!AST) {
987       StoreDiags CompilerInvocationDiagConsumer;
988       std::unique_ptr<CompilerInvocation> Invocation =
989           buildCompilerInvocation(FileInputs, CompilerInvocationDiagConsumer);
990       // Try rebuilding the AST.
991       vlog("ASTWorker rebuilding evicted AST to run {0}: {1} version {2}", Name,
992            FileName, FileInputs.Version);
993       // FIXME: We might need to build a patched ast once preamble thread starts
994       // running async. Currently getPossiblyStalePreamble below will always
995       // return a compatible preamble as ASTWorker::update blocks.
996       std::optional<ParsedAST> NewAST;
997       if (Invocation) {
998         NewAST = ParsedAST::build(FileName, FileInputs, std::move(Invocation),
999                                   CompilerInvocationDiagConsumer.take(),
1000                                   getPossiblyStalePreamble());
1001         ++ASTBuildCount;
1002       }
1003       AST = NewAST ? std::make_unique<ParsedAST>(std::move(*NewAST)) : nullptr;
1004     }
1005     // Make sure we put the AST back into the LRU cache.
1006     auto _ = llvm::make_scope_exit(
1007         [&AST, this]() { IdleASTs.put(this, std::move(*AST)); });
1008     // Run the user-provided action.
1009     if (!*AST)
1010       return Action(error(llvm::errc::invalid_argument, "invalid AST"));
1011     vlog("ASTWorker running {0} on version {2} of {1}", Name, FileName,
1012          FileInputs.Version);
1013     Action(InputsAndAST{FileInputs, **AST});
1014   };
1015   startTask(Name, std::move(Task), /*Update=*/std::nullopt, Invalidation);
1016 }
1017 
1018 /// To be called from ThreadCrashReporter's signal handler.
1019 static void crashDumpCompileCommand(llvm::raw_ostream &OS,
1020                                     const tooling::CompileCommand &Command) {
1021   OS << "  Filename: " << Command.Filename << "\n";
1022   OS << "  Directory: " << Command.Directory << "\n";
1023   OS << "  Command Line:";
1024   for (auto &Arg : Command.CommandLine) {
1025     OS << " " << Arg;
1026   }
1027   OS << "\n";
1028 }
1029 
1030 /// To be called from ThreadCrashReporter's signal handler.
1031 static void crashDumpFileContents(llvm::raw_ostream &OS,
1032                                   const std::string &Contents) {
1033   // Avoid flooding the terminal with source code by default, but allow clients
1034   // to opt in. Use an env var to preserve backwards compatibility of the
1035   // command line interface, while allowing it to be set outside the clangd
1036   // launch site for more flexibility.
1037   if (getenv("CLANGD_CRASH_DUMP_SOURCE")) {
1038     OS << "  Contents:\n";
1039     OS << Contents << "\n";
1040   }
1041 }
1042 
1043 /// To be called from ThreadCrashReporter's signal handler.
1044 static void crashDumpParseInputs(llvm::raw_ostream &OS,
1045                                  const ParseInputs &FileInputs) {
1046   auto &Command = FileInputs.CompileCommand;
1047   crashDumpCompileCommand(OS, Command);
1048   OS << "  Version: " << FileInputs.Version << "\n";
1049   crashDumpFileContents(OS, FileInputs.Contents);
1050 }
1051 
1052 void PreambleThread::build(Request Req) {
1053   assert(Req.CI && "Got preamble request with null compiler invocation");
1054   const ParseInputs &Inputs = Req.Inputs;
1055   bool ReusedPreamble = false;
1056 
1057   Status.update([&](TUStatus &Status) {
1058     Status.PreambleActivity = PreambleAction::Building;
1059   });
1060   auto _ = llvm::make_scope_exit([this, &Req, &ReusedPreamble] {
1061     ASTPeer.updatePreamble(std::move(Req.CI), std::move(Req.Inputs),
1062                            LatestBuild, std::move(Req.CIDiags),
1063                            std::move(Req.WantDiags));
1064     if (!ReusedPreamble)
1065       Callbacks.onPreamblePublished(FileName);
1066   });
1067 
1068   if (!LatestBuild || Inputs.ForceRebuild) {
1069     vlog("Building first preamble for {0} version {1}", FileName,
1070          Inputs.Version);
1071   } else if (isPreambleCompatible(*LatestBuild, Inputs, FileName, *Req.CI)) {
1072     vlog("Reusing preamble version {0} for version {1} of {2}",
1073          LatestBuild->Version, Inputs.Version, FileName);
1074     ReusedPreamble = true;
1075     return;
1076   } else {
1077     vlog("Rebuilding invalidated preamble for {0} version {1} (previous was "
1078          "version {2})",
1079          FileName, Inputs.Version, LatestBuild->Version);
1080   }
1081 
1082   ThreadCrashReporter ScopedReporter([&Inputs]() {
1083     llvm::errs() << "Signalled while building preamble\n";
1084     crashDumpParseInputs(llvm::errs(), Inputs);
1085   });
1086 
1087   PreambleBuildStats Stats;
1088   bool IsFirstPreamble = !LatestBuild;
1089   LatestBuild = clang::clangd::buildPreamble(
1090       FileName, *Req.CI, Inputs, StoreInMemory,
1091       [&](CapturedASTCtx ASTCtx,
1092           std::shared_ptr<const include_cleaner::PragmaIncludes> PI) {
1093         Callbacks.onPreambleAST(FileName, Inputs.Version, std::move(ASTCtx),
1094                                 std::move(PI));
1095       },
1096       &Stats);
1097   if (!LatestBuild)
1098     return;
1099   reportPreambleBuild(Stats, IsFirstPreamble);
1100   if (isReliable(LatestBuild->CompileCommand))
1101     HeaderIncluders.update(FileName, LatestBuild->Includes.allHeaders());
1102 }
1103 
1104 void ASTWorker::updatePreamble(std::unique_ptr<CompilerInvocation> CI,
1105                                ParseInputs PI,
1106                                std::shared_ptr<const PreambleData> Preamble,
1107                                std::vector<Diag> CIDiags,
1108                                WantDiagnostics WantDiags) {
1109   llvm::StringLiteral TaskName = "Build AST";
1110   // Store preamble and build diagnostics with new preamble if requested.
1111   auto Task = [this, Preamble = std::move(Preamble), CI = std::move(CI),
1112                CIDiags = std::move(CIDiags),
1113                WantDiags = std::move(WantDiags)]() mutable {
1114     // Update the preamble inside ASTWorker queue to ensure atomicity. As a task
1115     // running inside ASTWorker assumes internals won't change until it
1116     // finishes.
1117     if (!LatestPreamble || Preamble != *LatestPreamble) {
1118       ++PreambleBuildCount;
1119       // Cached AST is no longer valid.
1120       IdleASTs.take(this);
1121       RanASTCallback = false;
1122       std::lock_guard<std::mutex> Lock(Mutex);
1123       // LatestPreamble might be the last reference to old preamble, do not
1124       // trigger destructor while holding the lock.
1125       if (LatestPreamble)
1126         std::swap(*LatestPreamble, Preamble);
1127       else
1128         LatestPreamble = std::move(Preamble);
1129     }
1130     // Notify anyone waiting for a preamble.
1131     PreambleCV.notify_all();
1132     // Give up our ownership to old preamble before starting expensive AST
1133     // build.
1134     Preamble.reset();
1135     // We only need to build the AST if diagnostics were requested.
1136     if (WantDiags == WantDiagnostics::No)
1137       return;
1138     // Since the file may have been edited since we started building this
1139     // preamble, we use the current contents of the file instead. This provides
1140     // more up-to-date diagnostics, and avoids diagnostics going backwards (we
1141     // may have already emitted staler-preamble diagnostics for the new
1142     // version).
1143     // We still have eventual consistency: at some point updatePreamble() will
1144     // catch up to the current file.
1145     // Report diagnostics with the new preamble to ensure progress. Otherwise
1146     // diagnostics might get stale indefinitely if user keeps invalidating the
1147     // preamble.
1148     generateDiagnostics(std::move(CI), FileInputs, std::move(CIDiags));
1149   };
1150   if (RunSync) {
1151     runTask(TaskName, Task);
1152     return;
1153   }
1154   {
1155     std::lock_guard<std::mutex> Lock(Mutex);
1156     PreambleRequests.push_back({std::move(Task), std::string(TaskName),
1157                                 steady_clock::now(), Context::current().clone(),
1158                                 std::nullopt, std::nullopt,
1159                                 TUScheduler::NoInvalidation, nullptr});
1160   }
1161   PreambleCV.notify_all();
1162   RequestsCV.notify_all();
1163 }
1164 
1165 void ASTWorker::updateASTSignals(ParsedAST &AST) {
1166   auto Signals = std::make_shared<const ASTSignals>(ASTSignals::derive(AST));
1167   // Existing readers of ASTSignals will have their copy preserved until the
1168   // read is completed. The last reader deletes the old ASTSignals.
1169   {
1170     std::lock_guard<std::mutex> Lock(Mutex);
1171     std::swap(LatestASTSignals, Signals);
1172   }
1173 }
1174 
1175 void ASTWorker::generateDiagnostics(
1176     std::unique_ptr<CompilerInvocation> Invocation, ParseInputs Inputs,
1177     std::vector<Diag> CIDiags) {
1178   // Tracks ast cache accesses for publishing diags.
1179   static constexpr trace::Metric ASTAccessForDiag(
1180       "ast_access_diag", trace::Metric::Counter, "result");
1181   assert(Invocation);
1182   assert(LatestPreamble);
1183   // No need to rebuild the AST if we won't send the diagnostics.
1184   {
1185     std::lock_guard<std::mutex> Lock(PublishMu);
1186     if (!CanPublishResults)
1187       return;
1188   }
1189   // Used to check whether we can update AST cache.
1190   bool InputsAreLatest =
1191       std::tie(FileInputs.CompileCommand, FileInputs.Contents) ==
1192       std::tie(Inputs.CompileCommand, Inputs.Contents);
1193   // Take a shortcut and don't report the diagnostics, since they should be the
1194   // same. All the clients should handle the lack of OnUpdated() call anyway to
1195   // handle empty result from buildAST.
1196   // FIXME: the AST could actually change if non-preamble includes changed,
1197   // but we choose to ignore it.
1198   if (InputsAreLatest && RanASTCallback)
1199     return;
1200 
1201   // Get the AST for diagnostics, either build it or use the cached one.
1202   std::string TaskName = llvm::formatv("Build AST ({0})", Inputs.Version);
1203   Status.update([&](TUStatus &Status) {
1204     Status.ASTActivity.K = ASTAction::Building;
1205     Status.ASTActivity.Name = std::move(TaskName);
1206   });
1207   // We might be able to reuse the last we've built for a read request.
1208   // FIXME: It might be better to not reuse this AST. That way queued AST builds
1209   // won't be required for diags.
1210   std::optional<std::unique_ptr<ParsedAST>> AST =
1211       IdleASTs.take(this, &ASTAccessForDiag);
1212   if (!AST || !InputsAreLatest) {
1213     auto RebuildStartTime = DebouncePolicy::clock::now();
1214     std::optional<ParsedAST> NewAST = ParsedAST::build(
1215         FileName, Inputs, std::move(Invocation), CIDiags, *LatestPreamble);
1216     auto RebuildDuration = DebouncePolicy::clock::now() - RebuildStartTime;
1217     ++ASTBuildCount;
1218     // Try to record the AST-build time, to inform future update debouncing.
1219     // This is best-effort only: if the lock is held, don't bother.
1220     std::unique_lock<std::mutex> Lock(Mutex, std::try_to_lock);
1221     if (Lock.owns_lock()) {
1222       // Do not let RebuildTimes grow beyond its small-size (i.e.
1223       // capacity).
1224       if (RebuildTimes.size() == RebuildTimes.capacity())
1225         RebuildTimes.erase(RebuildTimes.begin());
1226       RebuildTimes.push_back(RebuildDuration);
1227       Lock.unlock();
1228     }
1229     Status.update([&](TUStatus &Status) {
1230       Status.Details.ReuseAST = false;
1231       Status.Details.BuildFailed = !NewAST;
1232     });
1233     AST = NewAST ? std::make_unique<ParsedAST>(std::move(*NewAST)) : nullptr;
1234   } else {
1235     log("Skipping rebuild of the AST for {0}, inputs are the same.", FileName);
1236     Status.update([](TUStatus &Status) {
1237       Status.Details.ReuseAST = true;
1238       Status.Details.BuildFailed = false;
1239     });
1240   }
1241 
1242   // Publish diagnostics.
1243   auto RunPublish = [&](llvm::function_ref<void()> Publish) {
1244     // Ensure we only publish results from the worker if the file was not
1245     // removed, making sure there are not race conditions.
1246     std::lock_guard<std::mutex> Lock(PublishMu);
1247     if (CanPublishResults)
1248       Publish();
1249   };
1250   if (*AST) {
1251     trace::Span Span("Running main AST callback");
1252     Callbacks.onMainAST(FileName, **AST, RunPublish);
1253     updateASTSignals(**AST);
1254   } else {
1255     // Failed to build the AST, at least report diagnostics from the
1256     // command line if there were any.
1257     // FIXME: we might have got more errors while trying to build the
1258     // AST, surface them too.
1259     Callbacks.onFailedAST(FileName, Inputs.Version, CIDiags, RunPublish);
1260   }
1261 
1262   // AST might've been built for an older version of the source, as ASTWorker
1263   // queue raced ahead while we were waiting on the preamble. In that case the
1264   // queue can't reuse the AST.
1265   if (InputsAreLatest) {
1266     RanASTCallback = *AST != nullptr;
1267     IdleASTs.put(this, std::move(*AST));
1268   }
1269 }
1270 
1271 std::shared_ptr<const PreambleData> ASTWorker::getPossiblyStalePreamble(
1272     std::shared_ptr<const ASTSignals> *ASTSignals) const {
1273   std::lock_guard<std::mutex> Lock(Mutex);
1274   if (ASTSignals)
1275     *ASTSignals = LatestASTSignals;
1276   return LatestPreamble ? *LatestPreamble : nullptr;
1277 }
1278 
1279 void ASTWorker::waitForFirstPreamble() const {
1280   std::unique_lock<std::mutex> Lock(Mutex);
1281   PreambleCV.wait(Lock, [this] { return LatestPreamble || Done; });
1282 }
1283 
1284 tooling::CompileCommand ASTWorker::getCurrentCompileCommand() const {
1285   std::unique_lock<std::mutex> Lock(Mutex);
1286   return FileInputs.CompileCommand;
1287 }
1288 
1289 TUScheduler::FileStats ASTWorker::stats() const {
1290   TUScheduler::FileStats Result;
1291   Result.ASTBuilds = ASTBuildCount;
1292   Result.PreambleBuilds = PreambleBuildCount;
1293   // Note that we don't report the size of ASTs currently used for processing
1294   // the in-flight requests. We used this information for debugging purposes
1295   // only, so this should be fine.
1296   Result.UsedBytesAST = IdleASTs.getUsedBytes(this);
1297   if (auto Preamble = getPossiblyStalePreamble())
1298     Result.UsedBytesPreamble = Preamble->Preamble.getSize();
1299   return Result;
1300 }
1301 
1302 bool ASTWorker::isASTCached() const { return IdleASTs.getUsedBytes(this) != 0; }
1303 
1304 void ASTWorker::stop() {
1305   {
1306     std::lock_guard<std::mutex> Lock(PublishMu);
1307     CanPublishResults = false;
1308   }
1309   {
1310     std::lock_guard<std::mutex> Lock(Mutex);
1311     assert(!Done && "stop() called twice");
1312     Done = true;
1313   }
1314   PreamblePeer.stop();
1315   // We are no longer going to build any preambles, let the waiters know that.
1316   PreambleCV.notify_all();
1317   Status.stop();
1318   RequestsCV.notify_all();
1319 }
1320 
1321 void ASTWorker::runTask(llvm::StringRef Name, llvm::function_ref<void()> Task) {
1322   ThreadCrashReporter ScopedReporter([this, Name]() {
1323     llvm::errs() << "Signalled during AST worker action: " << Name << "\n";
1324     crashDumpParseInputs(llvm::errs(), FileInputs);
1325   });
1326   trace::Span Tracer(Name);
1327   WithContext WithProvidedContext(ContextProvider(FileName));
1328   Task();
1329 }
1330 
1331 void ASTWorker::startTask(llvm::StringRef Name,
1332                           llvm::unique_function<void()> Task,
1333                           std::optional<UpdateType> Update,
1334                           TUScheduler::ASTActionInvalidation Invalidation) {
1335   if (RunSync) {
1336     assert(!Done && "running a task after stop()");
1337     runTask(Name, Task);
1338     return;
1339   }
1340 
1341   {
1342     std::lock_guard<std::mutex> Lock(Mutex);
1343     assert(!Done && "running a task after stop()");
1344     // Cancel any requests invalidated by this request.
1345     if (Update && Update->ContentChanged) {
1346       for (auto &R : llvm::reverse(Requests)) {
1347         if (R.InvalidationPolicy == TUScheduler::InvalidateOnUpdate)
1348           R.Invalidate();
1349         if (R.Update && R.Update->ContentChanged)
1350           break; // Older requests were already invalidated by the older update.
1351       }
1352     }
1353 
1354     // Allow this request to be cancelled if invalidated.
1355     Context Ctx = Context::current().derive(FileBeingProcessed, FileName);
1356     Canceler Invalidate = nullptr;
1357     if (Invalidation) {
1358       WithContext WC(std::move(Ctx));
1359       std::tie(Ctx, Invalidate) = cancelableTask(
1360           /*Reason=*/static_cast<int>(ErrorCode::ContentModified));
1361     }
1362     // Trace the time the request spends in the queue, and the requests that
1363     // it's going to wait for.
1364     std::optional<Context> QueueCtx;
1365     if (trace::enabled()) {
1366       // Tracers that follow threads and need strict nesting will see a tiny
1367       // instantaneous event "we're enqueueing", and sometime later it runs.
1368       WithContext WC(Ctx.clone());
1369       trace::Span Tracer("Queued:" + Name);
1370       if (Tracer.Args) {
1371         if (CurrentRequest)
1372           SPAN_ATTACH(Tracer, "CurrentRequest", CurrentRequest->Name);
1373         llvm::json::Array PreambleRequestsNames;
1374         for (const auto &Req : PreambleRequests)
1375           PreambleRequestsNames.push_back(Req.Name);
1376         SPAN_ATTACH(Tracer, "PreambleRequestsNames",
1377                     std::move(PreambleRequestsNames));
1378         llvm::json::Array RequestsNames;
1379         for (const auto &Req : Requests)
1380           RequestsNames.push_back(Req.Name);
1381         SPAN_ATTACH(Tracer, "RequestsNames", std::move(RequestsNames));
1382       }
1383       // For tracers that follow contexts, keep the trace span's context alive
1384       // until we dequeue the request, so they see the full duration.
1385       QueueCtx = Context::current().clone();
1386     }
1387     Requests.push_back({std::move(Task), std::string(Name), steady_clock::now(),
1388                         std::move(Ctx), std::move(QueueCtx), Update,
1389                         Invalidation, std::move(Invalidate)});
1390   }
1391   RequestsCV.notify_all();
1392 }
1393 
1394 void ASTWorker::run() {
1395   clang::noteBottomOfStack();
1396   while (true) {
1397     {
1398       std::unique_lock<std::mutex> Lock(Mutex);
1399       assert(!CurrentRequest && "A task is already running, multiple workers?");
1400       for (auto Wait = scheduleLocked(); !Wait.expired();
1401            Wait = scheduleLocked()) {
1402         assert(PreambleRequests.empty() &&
1403                "Preamble updates should be scheduled immediately");
1404         if (Done) {
1405           if (Requests.empty())
1406             return;
1407           // Even though Done is set, finish pending requests.
1408           break; // However, skip delays to shutdown fast.
1409         }
1410 
1411         // Tracing: we have a next request, attribute this sleep to it.
1412         std::optional<WithContext> Ctx;
1413         std::optional<trace::Span> Tracer;
1414         if (!Requests.empty()) {
1415           Ctx.emplace(Requests.front().Ctx.clone());
1416           Tracer.emplace("Debounce");
1417           SPAN_ATTACH(*Tracer, "next_request", Requests.front().Name);
1418           if (!(Wait == Deadline::infinity())) {
1419             Status.update([&](TUStatus &Status) {
1420               Status.ASTActivity.K = ASTAction::Queued;
1421               Status.ASTActivity.Name = Requests.front().Name;
1422             });
1423             SPAN_ATTACH(*Tracer, "sleep_ms",
1424                         std::chrono::duration_cast<std::chrono::milliseconds>(
1425                             Wait.time() - steady_clock::now())
1426                             .count());
1427           }
1428         }
1429 
1430         wait(Lock, RequestsCV, Wait);
1431       }
1432       // Any request in ReceivedPreambles is at least as old as the
1433       // Requests.front(), so prefer them first to preserve LSP order.
1434       if (!PreambleRequests.empty()) {
1435         CurrentRequest = std::move(PreambleRequests.front());
1436         PreambleRequests.pop_front();
1437       } else {
1438         CurrentRequest = std::move(Requests.front());
1439         Requests.pop_front();
1440       }
1441     } // unlock Mutex
1442 
1443     // Inform tracing that the request was dequeued.
1444     CurrentRequest->QueueCtx.reset();
1445 
1446     // It is safe to perform reads to CurrentRequest without holding the lock as
1447     // only writer is also this thread.
1448     {
1449       std::unique_lock<Semaphore> Lock(Barrier, std::try_to_lock);
1450       if (!Lock.owns_lock()) {
1451         Status.update([&](TUStatus &Status) {
1452           Status.ASTActivity.K = ASTAction::Queued;
1453           Status.ASTActivity.Name = CurrentRequest->Name;
1454         });
1455         Lock.lock();
1456       }
1457       WithContext Guard(std::move(CurrentRequest->Ctx));
1458       Status.update([&](TUStatus &Status) {
1459         Status.ASTActivity.K = ASTAction::RunningAction;
1460         Status.ASTActivity.Name = CurrentRequest->Name;
1461       });
1462       runTask(CurrentRequest->Name, CurrentRequest->Action);
1463     }
1464 
1465     bool IsEmpty = false;
1466     {
1467       std::lock_guard<std::mutex> Lock(Mutex);
1468       CurrentRequest.reset();
1469       IsEmpty = Requests.empty() && PreambleRequests.empty();
1470     }
1471     if (IsEmpty) {
1472       Status.update([&](TUStatus &Status) {
1473         Status.ASTActivity.K = ASTAction::Idle;
1474         Status.ASTActivity.Name = "";
1475       });
1476     }
1477     RequestsCV.notify_all();
1478   }
1479 }
1480 
1481 Deadline ASTWorker::scheduleLocked() {
1482   // Process new preambles immediately.
1483   if (!PreambleRequests.empty())
1484     return Deadline::zero();
1485   if (Requests.empty())
1486     return Deadline::infinity(); // Wait for new requests.
1487   // Handle cancelled requests first so the rest of the scheduler doesn't.
1488   for (auto I = Requests.begin(), E = Requests.end(); I != E; ++I) {
1489     if (!isCancelled(I->Ctx)) {
1490       // Cancellations after the first read don't affect current scheduling.
1491       if (I->Update == std::nullopt)
1492         break;
1493       continue;
1494     }
1495     // Cancelled reads are moved to the front of the queue and run immediately.
1496     if (I->Update == std::nullopt) {
1497       Request R = std::move(*I);
1498       Requests.erase(I);
1499       Requests.push_front(std::move(R));
1500       return Deadline::zero();
1501     }
1502     // Cancelled updates are downgraded to auto-diagnostics, and may be elided.
1503     if (I->Update->Diagnostics == WantDiagnostics::Yes)
1504       I->Update->Diagnostics = WantDiagnostics::Auto;
1505   }
1506 
1507   while (shouldSkipHeadLocked()) {
1508     vlog("ASTWorker skipping {0} for {1}", Requests.front().Name, FileName);
1509     Requests.pop_front();
1510   }
1511   assert(!Requests.empty() && "skipped the whole queue");
1512   // Some updates aren't dead yet, but never end up being used.
1513   // e.g. the first keystroke is live until obsoleted by the second.
1514   // We debounce "maybe-unused" writes, sleeping in case they become dead.
1515   // But don't delay reads (including updates where diagnostics are needed).
1516   for (const auto &R : Requests)
1517     if (R.Update == std::nullopt ||
1518         R.Update->Diagnostics == WantDiagnostics::Yes)
1519       return Deadline::zero();
1520   // Front request needs to be debounced, so determine when we're ready.
1521   Deadline D(Requests.front().AddTime + UpdateDebounce.compute(RebuildTimes));
1522   return D;
1523 }
1524 
1525 // Returns true if Requests.front() is a dead update that can be skipped.
1526 bool ASTWorker::shouldSkipHeadLocked() const {
1527   assert(!Requests.empty());
1528   auto Next = Requests.begin();
1529   auto Update = Next->Update;
1530   if (!Update) // Only skip updates.
1531     return false;
1532   ++Next;
1533   // An update is live if its AST might still be read.
1534   // That is, if it's not immediately followed by another update.
1535   if (Next == Requests.end() || !Next->Update)
1536     return false;
1537   // The other way an update can be live is if its diagnostics might be used.
1538   switch (Update->Diagnostics) {
1539   case WantDiagnostics::Yes:
1540     return false; // Always used.
1541   case WantDiagnostics::No:
1542     return true; // Always dead.
1543   case WantDiagnostics::Auto:
1544     // Used unless followed by an update that generates diagnostics.
1545     for (; Next != Requests.end(); ++Next)
1546       if (Next->Update && Next->Update->Diagnostics != WantDiagnostics::No)
1547         return true; // Prefer later diagnostics.
1548     return false;
1549   }
1550   llvm_unreachable("Unknown WantDiagnostics");
1551 }
1552 
1553 bool ASTWorker::blockUntilIdle(Deadline Timeout) const {
1554   auto WaitUntilASTWorkerIsIdle = [&] {
1555     std::unique_lock<std::mutex> Lock(Mutex);
1556     return wait(Lock, RequestsCV, Timeout, [&] {
1557       return PreambleRequests.empty() && Requests.empty() && !CurrentRequest;
1558     });
1559   };
1560   // Make sure ASTWorker has processed all requests, which might issue new
1561   // updates to PreamblePeer.
1562   if (!WaitUntilASTWorkerIsIdle())
1563     return false;
1564   // Now that ASTWorker processed all requests, ensure PreamblePeer has served
1565   // all update requests. This might create new PreambleRequests for the
1566   // ASTWorker.
1567   if (!PreamblePeer.blockUntilIdle(Timeout))
1568     return false;
1569   assert(Requests.empty() &&
1570          "No new normal tasks can be scheduled concurrently with "
1571          "blockUntilIdle(): ASTWorker isn't threadsafe");
1572   // Finally make sure ASTWorker has processed all of the preamble updates.
1573   return WaitUntilASTWorkerIsIdle();
1574 }
1575 
1576 // Render a TUAction to a user-facing string representation.
1577 // TUAction represents clangd-internal states, we don't intend to expose them
1578 // to users (say C++ programmers) directly to avoid confusion, we use terms that
1579 // are familiar by C++ programmers.
1580 std::string renderTUAction(const PreambleAction PA, const ASTAction &AA) {
1581   llvm::SmallVector<std::string, 2> Result;
1582   switch (PA) {
1583   case PreambleAction::Building:
1584     Result.push_back("parsing includes");
1585     break;
1586   case PreambleAction::Queued:
1587     Result.push_back("includes are queued");
1588     break;
1589   case PreambleAction::Idle:
1590     // We handle idle specially below.
1591     break;
1592   }
1593   switch (AA.K) {
1594   case ASTAction::Queued:
1595     Result.push_back("file is queued");
1596     break;
1597   case ASTAction::RunningAction:
1598     Result.push_back("running " + AA.Name);
1599     break;
1600   case ASTAction::Building:
1601     Result.push_back("parsing main file");
1602     break;
1603   case ASTAction::Idle:
1604     // We handle idle specially below.
1605     break;
1606   }
1607   if (Result.empty())
1608     return "idle";
1609   return llvm::join(Result, ", ");
1610 }
1611 
1612 } // namespace
1613 
1614 unsigned getDefaultAsyncThreadsCount() {
1615   return llvm::heavyweight_hardware_concurrency().compute_thread_count();
1616 }
1617 
1618 FileStatus TUStatus::render(PathRef File) const {
1619   FileStatus FStatus;
1620   FStatus.uri = URIForFile::canonicalize(File, /*TUPath=*/File);
1621   FStatus.state = renderTUAction(PreambleActivity, ASTActivity);
1622   return FStatus;
1623 }
1624 
1625 struct TUScheduler::FileData {
1626   /// Latest inputs, passed to TUScheduler::update().
1627   std::string Contents;
1628   ASTWorkerHandle Worker;
1629 };
1630 
1631 TUScheduler::TUScheduler(const GlobalCompilationDatabase &CDB,
1632                          const Options &Opts,
1633                          std::unique_ptr<ParsingCallbacks> Callbacks)
1634     : CDB(CDB), Opts(Opts),
1635       Callbacks(Callbacks ? std::move(Callbacks)
1636                           : std::make_unique<ParsingCallbacks>()),
1637       Barrier(Opts.AsyncThreadsCount), QuickRunBarrier(Opts.AsyncThreadsCount),
1638       IdleASTs(
1639           std::make_unique<ASTCache>(Opts.RetentionPolicy.MaxRetainedASTs)),
1640       HeaderIncluders(std::make_unique<HeaderIncluderCache>()) {
1641   // Avoid null checks everywhere.
1642   if (!Opts.ContextProvider) {
1643     this->Opts.ContextProvider = [](llvm::StringRef) {
1644       return Context::current().clone();
1645     };
1646   }
1647   if (0 < Opts.AsyncThreadsCount) {
1648     PreambleTasks.emplace();
1649     WorkerThreads.emplace();
1650   }
1651 }
1652 
1653 TUScheduler::~TUScheduler() {
1654   // Notify all workers that they need to stop.
1655   Files.clear();
1656 
1657   // Wait for all in-flight tasks to finish.
1658   if (PreambleTasks)
1659     PreambleTasks->wait();
1660   if (WorkerThreads)
1661     WorkerThreads->wait();
1662 }
1663 
1664 bool TUScheduler::blockUntilIdle(Deadline D) const {
1665   for (auto &File : Files)
1666     if (!File.getValue()->Worker->blockUntilIdle(D))
1667       return false;
1668   if (PreambleTasks)
1669     if (!PreambleTasks->wait(D))
1670       return false;
1671   return true;
1672 }
1673 
1674 bool TUScheduler::update(PathRef File, ParseInputs Inputs,
1675                          WantDiagnostics WantDiags) {
1676   std::unique_ptr<FileData> &FD = Files[File];
1677   bool NewFile = FD == nullptr;
1678   bool ContentChanged = false;
1679   if (!FD) {
1680     // Create a new worker to process the AST-related tasks.
1681     ASTWorkerHandle Worker = ASTWorker::create(
1682         File, CDB, *IdleASTs, *HeaderIncluders,
1683         WorkerThreads ? &*WorkerThreads : nullptr, Barrier, Opts, *Callbacks);
1684     FD = std::unique_ptr<FileData>(
1685         new FileData{Inputs.Contents, std::move(Worker)});
1686     ContentChanged = true;
1687   } else if (FD->Contents != Inputs.Contents) {
1688     ContentChanged = true;
1689     FD->Contents = Inputs.Contents;
1690   }
1691   FD->Worker->update(std::move(Inputs), WantDiags, ContentChanged);
1692   // There might be synthetic update requests, don't change the LastActiveFile
1693   // in such cases.
1694   if (ContentChanged)
1695     LastActiveFile = File.str();
1696   return NewFile;
1697 }
1698 
1699 void TUScheduler::remove(PathRef File) {
1700   bool Removed = Files.erase(File);
1701   if (!Removed)
1702     elog("Trying to remove file from TUScheduler that is not tracked: {0}",
1703          File);
1704   // We don't call HeaderIncluders.remove(File) here.
1705   // If we did, we'd avoid potentially stale header/mainfile associations.
1706   // However, it would mean that closing a mainfile could invalidate the
1707   // preamble of several open headers.
1708 }
1709 
1710 void TUScheduler::run(llvm::StringRef Name, llvm::StringRef Path,
1711                       llvm::unique_function<void()> Action) {
1712   runWithSemaphore(Name, Path, std::move(Action), Barrier);
1713 }
1714 
1715 void TUScheduler::runQuick(llvm::StringRef Name, llvm::StringRef Path,
1716                            llvm::unique_function<void()> Action) {
1717   // Use QuickRunBarrier to serialize quick tasks: we are ignoring
1718   // the parallelism level set by the user, don't abuse it
1719   runWithSemaphore(Name, Path, std::move(Action), QuickRunBarrier);
1720 }
1721 
1722 void TUScheduler::runWithSemaphore(llvm::StringRef Name, llvm::StringRef Path,
1723                                    llvm::unique_function<void()> Action,
1724                                    Semaphore &Sem) {
1725   if (Path.empty())
1726     Path = LastActiveFile;
1727   else
1728     LastActiveFile = Path.str();
1729   if (!PreambleTasks) {
1730     WithContext WithProvidedContext(Opts.ContextProvider(Path));
1731     return Action();
1732   }
1733   PreambleTasks->runAsync(Name, [this, &Sem, Ctx = Context::current().clone(),
1734                                  Path(Path.str()),
1735                                  Action = std::move(Action)]() mutable {
1736     std::lock_guard<Semaphore> BarrierLock(Sem);
1737     WithContext WC(std::move(Ctx));
1738     WithContext WithProvidedContext(Opts.ContextProvider(Path));
1739     Action();
1740   });
1741 }
1742 
1743 void TUScheduler::runWithAST(
1744     llvm::StringRef Name, PathRef File,
1745     llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action,
1746     TUScheduler::ASTActionInvalidation Invalidation) {
1747   auto It = Files.find(File);
1748   if (It == Files.end()) {
1749     Action(llvm::make_error<LSPError>(
1750         "trying to get AST for non-added document", ErrorCode::InvalidParams));
1751     return;
1752   }
1753   LastActiveFile = File.str();
1754 
1755   It->second->Worker->runWithAST(Name, std::move(Action), Invalidation);
1756 }
1757 
1758 void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
1759                                   PreambleConsistency Consistency,
1760                                   Callback<InputsAndPreamble> Action) {
1761   auto It = Files.find(File);
1762   if (It == Files.end()) {
1763     Action(llvm::make_error<LSPError>(
1764         "trying to get preamble for non-added document",
1765         ErrorCode::InvalidParams));
1766     return;
1767   }
1768   LastActiveFile = File.str();
1769 
1770   if (!PreambleTasks) {
1771     trace::Span Tracer(Name);
1772     SPAN_ATTACH(Tracer, "file", File);
1773     std::shared_ptr<const ASTSignals> Signals;
1774     std::shared_ptr<const PreambleData> Preamble =
1775         It->second->Worker->getPossiblyStalePreamble(&Signals);
1776     WithContext WithProvidedContext(Opts.ContextProvider(File));
1777     Action(InputsAndPreamble{It->second->Contents,
1778                              It->second->Worker->getCurrentCompileCommand(),
1779                              Preamble.get(), Signals.get()});
1780     return;
1781   }
1782 
1783   std::shared_ptr<const ASTWorker> Worker = It->second->Worker.lock();
1784   auto Task = [Worker, Consistency, Name = Name.str(), File = File.str(),
1785                Contents = It->second->Contents,
1786                Command = Worker->getCurrentCompileCommand(),
1787                Ctx = Context::current().derive(FileBeingProcessed,
1788                                                std::string(File)),
1789                Action = std::move(Action), this]() mutable {
1790     clang::noteBottomOfStack();
1791     ThreadCrashReporter ScopedReporter([&Name, &Contents, &Command]() {
1792       llvm::errs() << "Signalled during preamble action: " << Name << "\n";
1793       crashDumpCompileCommand(llvm::errs(), Command);
1794       crashDumpFileContents(llvm::errs(), Contents);
1795     });
1796     std::shared_ptr<const PreambleData> Preamble;
1797     if (Consistency == PreambleConsistency::Stale) {
1798       // Wait until the preamble is built for the first time, if preamble
1799       // is required. This avoids extra work of processing the preamble
1800       // headers in parallel multiple times.
1801       Worker->waitForFirstPreamble();
1802     }
1803     std::shared_ptr<const ASTSignals> Signals;
1804     Preamble = Worker->getPossiblyStalePreamble(&Signals);
1805 
1806     std::lock_guard<Semaphore> BarrierLock(Barrier);
1807     WithContext Guard(std::move(Ctx));
1808     trace::Span Tracer(Name);
1809     SPAN_ATTACH(Tracer, "file", File);
1810     WithContext WithProvidedContext(Opts.ContextProvider(File));
1811     Action(InputsAndPreamble{Contents, Command, Preamble.get(), Signals.get()});
1812   };
1813 
1814   PreambleTasks->runAsync("task:" + llvm::sys::path::filename(File),
1815                           std::move(Task));
1816 }
1817 
1818 llvm::StringMap<TUScheduler::FileStats> TUScheduler::fileStats() const {
1819   llvm::StringMap<TUScheduler::FileStats> Result;
1820   for (const auto &PathAndFile : Files)
1821     Result.try_emplace(PathAndFile.first(),
1822                        PathAndFile.second->Worker->stats());
1823   return Result;
1824 }
1825 
1826 std::vector<Path> TUScheduler::getFilesWithCachedAST() const {
1827   std::vector<Path> Result;
1828   for (auto &&PathAndFile : Files) {
1829     if (!PathAndFile.second->Worker->isASTCached())
1830       continue;
1831     Result.push_back(std::string(PathAndFile.first()));
1832   }
1833   return Result;
1834 }
1835 
1836 DebouncePolicy::clock::duration
1837 DebouncePolicy::compute(llvm::ArrayRef<clock::duration> History) const {
1838   assert(Min <= Max && "Invalid policy");
1839   if (History.empty())
1840     return Max; // Arbitrary.
1841 
1842   // Base the result on the median rebuild.
1843   // nth_element needs a mutable array, take the chance to bound the data size.
1844   History = History.take_back(15);
1845   llvm::SmallVector<clock::duration, 15> Recent(History);
1846   auto *Median = Recent.begin() + Recent.size() / 2;
1847   std::nth_element(Recent.begin(), Median, Recent.end());
1848 
1849   clock::duration Target =
1850       std::chrono::duration_cast<clock::duration>(RebuildRatio * *Median);
1851   if (Target > Max)
1852     return Max;
1853   if (Target < Min)
1854     return Min;
1855   return Target;
1856 }
1857 
1858 DebouncePolicy DebouncePolicy::fixed(clock::duration T) {
1859   DebouncePolicy P;
1860   P.Min = P.Max = T;
1861   return P;
1862 }
1863 
1864 void TUScheduler::profile(MemoryTree &MT) const {
1865   for (const auto &Elem : fileStats()) {
1866     MT.detail(Elem.first())
1867         .child("preamble")
1868         .addUsage(Opts.StorePreamblesInMemory ? Elem.second.UsedBytesPreamble
1869                                               : 0);
1870     MT.detail(Elem.first()).child("ast").addUsage(Elem.second.UsedBytesAST);
1871     MT.child("header_includer_cache").addUsage(HeaderIncluders->getUsedBytes());
1872   }
1873 }
1874 } // namespace clangd
1875 } // namespace clang
1876