Skip to content

Commit ed98994

Browse files
committed
Revert "[clangd] Mechanism to make update debounce responsive to rebuild speed."
This reverts commit 9257071. Breaking tests: http://45.33.8.238/linux/9296/step_9.txt
1 parent d4c8230 commit ed98994

File tree

5 files changed

+14
-109
lines changed

5 files changed

+14
-109
lines changed

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ struct UpdateIndexCallbacks : public ParsingCallbacks {
106106

107107
ClangdServer::Options ClangdServer::optsForTest() {
108108
ClangdServer::Options Opts;
109-
Opts.UpdateDebounce = DebouncePolicy::fixed(/*zero*/ {});
109+
Opts.UpdateDebounce = std::chrono::steady_clock::duration::zero(); // Faster!
110110
Opts.StorePreamblesInMemory = true;
111111
Opts.AsyncThreadsCount = 4; // Consistent!
112112
Opts.SemanticHighlighting = true;

clang-tools-extra/clangd/ClangdServer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ class ClangdServer {
130130
llvm::Optional<std::string> ResourceDir = llvm::None;
131131

132132
/// Time to wait after a new file version before computing diagnostics.
133-
DebouncePolicy UpdateDebounce =
134-
DebouncePolicy::fixed(std::chrono::milliseconds(500));
133+
std::chrono::steady_clock::duration UpdateDebounce =
134+
std::chrono::milliseconds(500);
135135

136136
bool SuggestMissingIncludes = false;
137137

clang-tools-extra/clangd/TUScheduler.cpp

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
#include "llvm/Support/Threading.h"
6262
#include <algorithm>
6363
#include <memory>
64-
#include <mutex>
6564
#include <queue>
6665
#include <thread>
6766

@@ -165,7 +164,7 @@ class ASTWorker {
165164
friend class ASTWorkerHandle;
166165
ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
167166
TUScheduler::ASTCache &LRUCache, Semaphore &Barrier, bool RunSync,
168-
DebouncePolicy UpdateDebounce, bool StorePreamblesInMemory,
167+
steady_clock::duration UpdateDebounce, bool StorePreamblesInMemory,
169168
ParsingCallbacks &Callbacks);
170169

171170
public:
@@ -177,7 +176,7 @@ class ASTWorker {
177176
static ASTWorkerHandle
178177
create(PathRef FileName, const GlobalCompilationDatabase &CDB,
179178
TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks,
180-
Semaphore &Barrier, DebouncePolicy UpdateDebounce,
179+
Semaphore &Barrier, steady_clock::duration UpdateDebounce,
181180
bool StorePreamblesInMemory, ParsingCallbacks &Callbacks);
182181
~ASTWorker();
183182

@@ -243,7 +242,7 @@ class ASTWorker {
243242
TUScheduler::ASTCache &IdleASTs;
244243
const bool RunSync;
245244
/// Time to wait after an update to see whether another update obsoletes it.
246-
const DebouncePolicy UpdateDebounce;
245+
const steady_clock::duration UpdateDebounce;
247246
/// File that ASTWorker is responsible for.
248247
const Path FileName;
249248
const GlobalCompilationDatabase &CDB;
@@ -264,9 +263,6 @@ class ASTWorker {
264263
/// be consumed by clients of ASTWorker.
265264
std::shared_ptr<const ParseInputs> FileInputs; /* GUARDED_BY(Mutex) */
266265
std::shared_ptr<const PreambleData> LastBuiltPreamble; /* GUARDED_BY(Mutex) */
267-
/// Times of recent AST rebuilds, used for UpdateDebounce computation.
268-
llvm::SmallVector<DebouncePolicy::clock::duration, 8>
269-
RebuildTimes; /* GUARDED_BY(Mutex) */
270266
/// Becomes ready when the first preamble build finishes.
271267
Notification PreambleWasBuilt;
272268
/// Set to true to signal run() to finish processing.
@@ -330,7 +326,7 @@ class ASTWorkerHandle {
330326
ASTWorkerHandle
331327
ASTWorker::create(PathRef FileName, const GlobalCompilationDatabase &CDB,
332328
TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks,
333-
Semaphore &Barrier, DebouncePolicy UpdateDebounce,
329+
Semaphore &Barrier, steady_clock::duration UpdateDebounce,
334330
bool StorePreamblesInMemory, ParsingCallbacks &Callbacks) {
335331
std::shared_ptr<ASTWorker> Worker(
336332
new ASTWorker(FileName, CDB, IdleASTs, Barrier, /*RunSync=*/!Tasks,
@@ -344,7 +340,7 @@ ASTWorker::create(PathRef FileName, const GlobalCompilationDatabase &CDB,
344340

345341
ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
346342
TUScheduler::ASTCache &LRUCache, Semaphore &Barrier,
347-
bool RunSync, DebouncePolicy UpdateDebounce,
343+
bool RunSync, steady_clock::duration UpdateDebounce,
348344
bool StorePreamblesInMemory, ParsingCallbacks &Callbacks)
349345
: IdleASTs(LRUCache), RunSync(RunSync), UpdateDebounce(UpdateDebounce),
350346
FileName(FileName), CDB(CDB),
@@ -492,7 +488,6 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) {
492488

493489
// Get the AST for diagnostics.
494490
llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
495-
auto RebuildStartTime = DebouncePolicy::clock::now();
496491
if (!AST) {
497492
llvm::Optional<ParsedAST> NewAST =
498493
buildAST(FileName, std::move(Invocation), CompilerInvocationDiags,
@@ -515,19 +510,6 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) {
515510
// spam us with updates.
516511
// Note *AST can still be null if buildAST fails.
517512
if (*AST) {
518-
{
519-
// Try to record the AST-build time, to inform future update debouncing.
520-
// This is best-effort only: if the lock is held, don't bother.
521-
auto RebuildDuration = DebouncePolicy::clock::now() - RebuildStartTime;
522-
std::unique_lock<std::mutex> Lock(Mutex, std::try_to_lock);
523-
if (Lock.owns_lock()) {
524-
// Do not let RebuildTimes grow beyond its small-size (i.e. capacity).
525-
if (RebuildTimes.size() == RebuildTimes.capacity())
526-
RebuildTimes.erase(RebuildTimes.begin());
527-
RebuildTimes.push_back(RebuildDuration);
528-
Mutex.unlock();
529-
}
530-
}
531513
trace::Span Span("Running main AST callback");
532514

533515
Callbacks.onMainAST(FileName, **AST, RunPublish);
@@ -768,13 +750,13 @@ Deadline ASTWorker::scheduleLocked() {
768750
assert(!Requests.empty() && "skipped the whole queue");
769751
// Some updates aren't dead yet, but never end up being used.
770752
// e.g. the first keystroke is live until obsoleted by the second.
771-
// We debounce "maybe-unused" writes, sleeping in case they become dead.
753+
// We debounce "maybe-unused" writes, sleeping 500ms in case they become dead.
772754
// But don't delay reads (including updates where diagnostics are needed).
773755
for (const auto &R : Requests)
774756
if (R.UpdateType == None || R.UpdateType == WantDiagnostics::Yes)
775757
return Deadline::zero();
776758
// Front request needs to be debounced, so determine when we're ready.
777-
Deadline D(Requests.front().AddTime + UpdateDebounce.compute(RebuildTimes));
759+
Deadline D(Requests.front().AddTime + UpdateDebounce);
778760
return D;
779761
}
780762

@@ -1054,33 +1036,5 @@ std::vector<Path> TUScheduler::getFilesWithCachedAST() const {
10541036
return Result;
10551037
}
10561038

1057-
DebouncePolicy::clock::duration
1058-
DebouncePolicy::compute(llvm::ArrayRef<clock::duration> History) const {
1059-
assert(Min <= Max && "Invalid policy");
1060-
if (History.empty())
1061-
return Max; // Arbitrary.
1062-
1063-
// Base the result on the median rebuild.
1064-
// nth_element needs a mutable array, take the chance to bound the data size.
1065-
History = History.take_back(15);
1066-
llvm::SmallVector<clock::duration, 15> Recent(History.begin(), History.end());
1067-
auto Median = Recent.begin() + Recent.size() / 2;
1068-
std::nth_element(Recent.begin(), Median, Recent.end());
1069-
1070-
clock::duration Target =
1071-
std::chrono::duration_cast<clock::duration>(RebuildRatio * *Median);
1072-
if (Target > Max)
1073-
return Max;
1074-
if (Target < Min)
1075-
return Min;
1076-
return Target;
1077-
}
1078-
1079-
DebouncePolicy DebouncePolicy::fixed(clock::duration T) {
1080-
DebouncePolicy P;
1081-
P.Min = P.Max = T;
1082-
return P;
1083-
}
1084-
10851039
} // namespace clangd
10861040
} // namespace clang

clang-tools-extra/clangd/TUScheduler.h

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,6 @@ struct ASTRetentionPolicy {
6161
unsigned MaxRetainedASTs = 3;
6262
};
6363

64-
/// Clangd may wait after an update to see if another one comes along.
65-
/// This is so we rebuild once the user stops typing, not when they start.
66-
/// Debounce may be disabled/interrupted if we must build this version.
67-
/// The debounce time is responsive to user preferences and rebuild time.
68-
/// In the future, we could also consider different types of edits.
69-
struct DebouncePolicy {
70-
using clock = std::chrono::steady_clock;
71-
72-
/// The minimum time that we always debounce for.
73-
clock::duration Min = /*zero*/ {};
74-
/// The maximum time we may debounce for.
75-
clock::duration Max = /*zero*/ {};
76-
/// Target debounce, as a fraction of file rebuild time.
77-
/// e.g. RebuildRatio = 2, recent builds took 200ms => debounce for 400ms.
78-
float RebuildRatio = 1;
79-
80-
/// Compute the time to debounce based on this policy and recent build times.
81-
clock::duration compute(llvm::ArrayRef<clock::duration> History) const;
82-
/// A policy that always returns the same duration, useful for tests.
83-
static DebouncePolicy fixed(clock::duration);
84-
};
85-
8664
struct TUAction {
8765
enum State {
8866
Queued, // The TU is pending in the thread task queue to be built.
@@ -180,7 +158,7 @@ class TUScheduler {
180158

181159
/// Time to wait after an update to see if another one comes along.
182160
/// This tries to ensure we rebuild once the user stops typing.
183-
DebouncePolicy UpdateDebounce;
161+
std::chrono::steady_clock::duration UpdateDebounce = /*zero*/ {};
184162

185163
/// Determines when to keep idle ASTs in memory for future use.
186164
ASTRetentionPolicy RetentionPolicy;
@@ -295,7 +273,7 @@ class TUScheduler {
295273
// asynchronously.
296274
llvm::Optional<AsyncTaskRunner> PreambleTasks;
297275
llvm::Optional<AsyncTaskRunner> WorkerThreads;
298-
DebouncePolicy UpdateDebounce;
276+
std::chrono::steady_clock::duration UpdateDebounce;
299277
};
300278

301279
} // namespace clangd

clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "gmock/gmock.h"
2424
#include "gtest/gtest.h"
2525
#include <algorithm>
26-
#include <chrono>
2726
#include <utility>
2827

2928
namespace clang {
@@ -209,7 +208,7 @@ TEST_F(TUSchedulerTests, Debounce) {
209208
std::atomic<int> CallbackCount(0);
210209
{
211210
auto Opts = optsForTest();
212-
Opts.UpdateDebounce = DebouncePolicy::fixed(std::chrono::seconds(1));
211+
Opts.UpdateDebounce = std::chrono::seconds(1);
213212
TUScheduler S(CDB, Opts, captureDiags());
214213
// FIXME: we could probably use timeouts lower than 1 second here.
215214
auto Path = testPath("foo.cpp");
@@ -362,7 +361,7 @@ TEST_F(TUSchedulerTests, ManyUpdates) {
362361
// Run TUScheduler and collect some stats.
363362
{
364363
auto Opts = optsForTest();
365-
Opts.UpdateDebounce = DebouncePolicy::fixed(std::chrono::milliseconds(50));
364+
Opts.UpdateDebounce = std::chrono::milliseconds(50);
366365
TUScheduler S(CDB, Opts, captureDiags());
367366

368367
std::vector<std::string> Files;
@@ -755,32 +754,6 @@ TEST_F(TUSchedulerTests, CommandLineWarnings) {
755754
EXPECT_THAT(Diagnostics, IsEmpty());
756755
}
757756

758-
TEST(DebouncePolicy, Compute) {
759-
namespace c = std::chrono;
760-
std::vector<DebouncePolicy::clock::duration> History = {
761-
c::seconds(0),
762-
c::seconds(5),
763-
c::seconds(10),
764-
c::seconds(20),
765-
};
766-
DebouncePolicy Policy;
767-
Policy.Min = c::seconds(3);
768-
Policy.Max = c::seconds(25);
769-
// Call Policy.compute(History) and return seconds as a float.
770-
auto Compute = [&](llvm::ArrayRef<DebouncePolicy::clock::duration> History) {
771-
using FloatingSeconds = c::duration<float, c::seconds::period>;
772-
return static_cast<float>(Policy.compute(History) / FloatingSeconds(1));
773-
};
774-
EXPECT_NEAR(10, Compute(History), 0.01) << "(upper) median = 10";
775-
Policy.RebuildRatio = 1.5;
776-
EXPECT_NEAR(15, Compute(History), 0.01) << "median = 10, ratio = 1.5";
777-
Policy.RebuildRatio = 3;
778-
EXPECT_NEAR(25, Compute(History), 0.01) << "constrained by max";
779-
Policy.RebuildRatio = 0;
780-
EXPECT_NEAR(3, Compute(History), 0.01) << "constrained by min";
781-
EXPECT_NEAR(25, Compute({}), 0.01) << "no history -> max";
782-
}
783-
784757
} // namespace
785758
} // namespace clangd
786759
} // namespace clang

0 commit comments

Comments
 (0)