comparison clang-tools-extra/clangd/TUScheduler.h @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents 0572611fdcc8
children c4bab56944e8
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 8
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H
11 11
12 #include "ASTSignals.h"
12 #include "Compiler.h" 13 #include "Compiler.h"
13 #include "Diagnostics.h" 14 #include "Diagnostics.h"
14 #include "GlobalCompilationDatabase.h" 15 #include "GlobalCompilationDatabase.h"
15 #include "index/CanonicalIncludes.h" 16 #include "index/CanonicalIncludes.h"
16 #include "support/Function.h" 17 #include "support/Function.h"
18 #include "support/MemoryTree.h"
17 #include "support/Path.h" 19 #include "support/Path.h"
18 #include "support/Threading.h" 20 #include "support/Threading.h"
19 #include "llvm/ADT/Optional.h" 21 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/StringMap.h" 23 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringRef.h" 24 #include "llvm/ADT/StringRef.h"
23 #include <chrono> 25 #include <chrono>
26 #include <string>
24 27
25 namespace clang { 28 namespace clang {
26 namespace clangd { 29 namespace clangd {
27 class ParsedAST; 30 class ParsedAST;
28 struct PreambleData; 31 struct PreambleData;
40 struct InputsAndPreamble { 43 struct InputsAndPreamble {
41 llvm::StringRef Contents; 44 llvm::StringRef Contents;
42 const tooling::CompileCommand &Command; 45 const tooling::CompileCommand &Command;
43 // This can be nullptr if no preamble is available. 46 // This can be nullptr if no preamble is available.
44 const PreambleData *Preamble; 47 const PreambleData *Preamble;
48 // This can be nullptr if no ASTSignals are available.
49 const ASTSignals *Signals;
45 }; 50 };
46 51
47 /// Determines whether diagnostics should be generated for a file snapshot. 52 /// Determines whether diagnostics should be generated for a file snapshot.
48 enum class WantDiagnostics { 53 enum class WantDiagnostics {
49 Yes, /// Diagnostics must be generated for this snapshot. 54 Yes, /// Diagnostics must be generated for this snapshot.
145 /// accessed from the main file AST, e.g. redecls of functions from preamble, 150 /// accessed from the main file AST, e.g. redecls of functions from preamble,
146 /// etc. Clients are expected to process only the AST nodes from the main file 151 /// etc. Clients are expected to process only the AST nodes from the main file
147 /// in this callback (obtained via ParsedAST::getLocalTopLevelDecls) to obtain 152 /// in this callback (obtained via ParsedAST::getLocalTopLevelDecls) to obtain
148 /// optimal performance. 153 /// optimal performance.
149 /// 154 ///
150 /// When information about the file (diagnostics, syntax highlighting) is 155 /// When information about the file (e.g. diagnostics) is
151 /// published to clients, this should be wrapped in Publish, e.g. 156 /// published to clients, this should be wrapped in Publish, e.g.
152 /// void onMainAST(...) { 157 /// void onMainAST(...) {
153 /// Highlights = computeHighlights(); 158 /// Diags = renderDiagnostics();
154 /// Publish([&] { notifyHighlights(Path, Highlights); }); 159 /// Publish([&] { notifyDiagnostics(Path, Diags); });
155 /// } 160 /// }
156 /// This guarantees that clients will see results in the correct sequence if 161 /// This guarantees that clients will see results in the correct sequence if
157 /// the file is concurrently closed and/or reopened. (The lambda passed to 162 /// the file is concurrently closed and/or reopened. (The lambda passed to
158 /// Publish() may never run in this case). 163 /// Publish() may never run in this case).
159 virtual void onMainAST(PathRef Path, ParsedAST &AST, PublishFn Publish) {} 164 virtual void onMainAST(PathRef Path, ParsedAST &AST, PublishFn Publish) {}
163 virtual void onFailedAST(PathRef Path, llvm::StringRef Version, 168 virtual void onFailedAST(PathRef Path, llvm::StringRef Version,
164 std::vector<Diag> Diags, PublishFn Publish) {} 169 std::vector<Diag> Diags, PublishFn Publish) {}
165 170
166 /// Called whenever the TU status is updated. 171 /// Called whenever the TU status is updated.
167 virtual void onFileUpdated(PathRef File, const TUStatus &Status) {} 172 virtual void onFileUpdated(PathRef File, const TUStatus &Status) {}
173
174 /// Preamble for the TU have changed. This might imply new semantics (e.g.
175 /// different highlightings). Any actions on the file are guranteed to see new
176 /// preamble after the callback.
177 virtual void onPreamblePublished(PathRef File) {}
168 }; 178 };
169 179
170 /// Handles running tasks for ClangdServer and managing the resources (e.g., 180 /// Handles running tasks for ClangdServer and managing the resources (e.g.,
171 /// preambles and ASTs) for opened files. 181 /// preambles and ASTs) for opened files.
172 /// TUScheduler is not thread-safe, only one thread should be providing updates 182 /// TUScheduler is not thread-safe, only one thread should be providing updates
189 /// This tries to ensure we rebuild once the user stops typing. 199 /// This tries to ensure we rebuild once the user stops typing.
190 DebouncePolicy UpdateDebounce; 200 DebouncePolicy UpdateDebounce;
191 201
192 /// Determines when to keep idle ASTs in memory for future use. 202 /// Determines when to keep idle ASTs in memory for future use.
193 ASTRetentionPolicy RetentionPolicy; 203 ASTRetentionPolicy RetentionPolicy;
204
205 /// Used to create a context that wraps each single operation.
206 /// Typically to inject per-file configuration.
207 /// If the path is empty, context sholud be "generic".
208 std::function<Context(PathRef)> ContextProvider;
194 }; 209 };
195 210
196 TUScheduler(const GlobalCompilationDatabase &CDB, const Options &Opts, 211 TUScheduler(const GlobalCompilationDatabase &CDB, const Options &Opts,
197 std::unique_ptr<ParsingCallbacks> ASTCallbacks = nullptr); 212 std::unique_ptr<ParsingCallbacks> ASTCallbacks = nullptr);
198 ~TUScheduler(); 213 ~TUScheduler();
199 214
200 struct FileStats { 215 struct FileStats {
201 std::size_t UsedBytes = 0; 216 std::size_t UsedBytesAST = 0;
217 std::size_t UsedBytesPreamble = 0;
202 unsigned PreambleBuilds = 0; 218 unsigned PreambleBuilds = 0;
203 unsigned ASTBuilds = 0; 219 unsigned ASTBuilds = 0;
204 }; 220 };
205 /// Returns resources used for each of the currently open files. 221 /// Returns resources used for each of the currently open files.
206 /// Results are inherently racy as they measure activity of other threads. 222 /// Results are inherently racy as they measure activity of other threads.
223 /// Remove \p File from the list of tracked files and schedule removal of its 239 /// Remove \p File from the list of tracked files and schedule removal of its
224 /// resources. Pending diagnostics for closed files may not be delivered, even 240 /// resources. Pending diagnostics for closed files may not be delivered, even
225 /// if requested with WantDiags::Auto or WantDiags::Yes. 241 /// if requested with WantDiags::Auto or WantDiags::Yes.
226 void remove(PathRef File); 242 void remove(PathRef File);
227 243
228 /// Returns a snapshot of all file buffer contents, per last update().
229 llvm::StringMap<std::string> getAllFileContents() const;
230
231 /// Schedule an async task with no dependencies. 244 /// Schedule an async task with no dependencies.
232 void run(llvm::StringRef Name, llvm::unique_function<void()> Action); 245 /// Path may be empty (it is used only to set the Context).
246 void run(llvm::StringRef Name, llvm::StringRef Path,
247 llvm::unique_function<void()> Action);
248
249 /// Similar to run, except the task is expected to be quick.
250 /// This function will not honor AsyncThreadsCount (except
251 /// if threading is disabled with AsyncThreadsCount=0)
252 /// It is intended to run quick tasks that need to run ASAP
253 void runQuick(llvm::StringRef Name, llvm::StringRef Path,
254 llvm::unique_function<void()> Action);
233 255
234 /// Defines how a runWithAST action is implicitly cancelled by other actions. 256 /// Defines how a runWithAST action is implicitly cancelled by other actions.
235 enum ASTActionInvalidation { 257 enum ASTActionInvalidation {
236 /// The request will run unless explicitly cancelled. 258 /// The request will run unless explicitly cancelled.
237 NoInvalidation, 259 NoInvalidation,
289 311
290 public: 312 public:
291 /// Responsible for retaining and rebuilding idle ASTs. An implementation is 313 /// Responsible for retaining and rebuilding idle ASTs. An implementation is
292 /// an LRU cache. 314 /// an LRU cache.
293 class ASTCache; 315 class ASTCache;
316 /// Tracks headers included by open files, to get known-good compile commands.
317 class HeaderIncluderCache;
294 318
295 // The file being built/processed in the current thread. This is a hack in 319 // The file being built/processed in the current thread. This is a hack in
296 // order to get the file name into the index implementations. Do not depend on 320 // order to get the file name into the index implementations. Do not depend on
297 // this inside clangd. 321 // this inside clangd.
298 // FIXME: remove this when there is proper index support via build system 322 // FIXME: remove this when there is proper index support via build system
299 // integration. 323 // integration.
324 // FIXME: move to ClangdServer via createProcessingContext.
300 static llvm::Optional<llvm::StringRef> getFileBeingProcessedInContext(); 325 static llvm::Optional<llvm::StringRef> getFileBeingProcessedInContext();
301 326
327 void profile(MemoryTree &MT) const;
328
302 private: 329 private:
330 void runWithSemaphore(llvm::StringRef Name, llvm::StringRef Path,
331 llvm::unique_function<void()> Action, Semaphore &Sem);
332
303 const GlobalCompilationDatabase &CDB; 333 const GlobalCompilationDatabase &CDB;
304 const bool StorePreamblesInMemory; 334 Options Opts;
305 std::unique_ptr<ParsingCallbacks> Callbacks; // not nullptr 335 std::unique_ptr<ParsingCallbacks> Callbacks; // not nullptr
306 Semaphore Barrier; 336 Semaphore Barrier;
337 Semaphore QuickRunBarrier;
307 llvm::StringMap<std::unique_ptr<FileData>> Files; 338 llvm::StringMap<std::unique_ptr<FileData>> Files;
308 std::unique_ptr<ASTCache> IdleASTs; 339 std::unique_ptr<ASTCache> IdleASTs;
340 std::unique_ptr<HeaderIncluderCache> HeaderIncluders;
309 // None when running tasks synchronously and non-None when running tasks 341 // None when running tasks synchronously and non-None when running tasks
310 // asynchronously. 342 // asynchronously.
311 llvm::Optional<AsyncTaskRunner> PreambleTasks; 343 llvm::Optional<AsyncTaskRunner> PreambleTasks;
312 llvm::Optional<AsyncTaskRunner> WorkerThreads; 344 llvm::Optional<AsyncTaskRunner> WorkerThreads;
313 DebouncePolicy UpdateDebounce; 345 // Used to create contexts for operations that are not bound to a particular
346 // file (e.g. index queries).
347 std::string LastActiveFile;
314 }; 348 };
315 349
316 } // namespace clangd 350 } // namespace clangd
317 } // namespace clang 351 } // namespace clang
318 352