@@ -465,6 +465,7 @@ class ASTWorker {
465
465
std::string Name;
466
466
steady_clock::time_point AddTime;
467
467
Context Ctx;
468
+ llvm::Optional<Context> QueueCtx;
468
469
llvm::Optional<UpdateType> Update;
469
470
TUScheduler::ASTActionInvalidation InvalidationPolicy;
470
471
Canceler Invalidate;
@@ -507,7 +508,7 @@ class ASTWorker {
507
508
// / None means no builds yet, null means there was an error while building.
508
509
// / Only written by ASTWorker's thread.
509
510
llvm::Optional<std::shared_ptr<const PreambleData>> LatestPreamble;
510
- std::queue <Request> PreambleRequests; /* GUARDED_BY(Mutex) */
511
+ std::deque <Request> PreambleRequests; /* GUARDED_BY(Mutex) */
511
512
// / Signaled whenever LatestPreamble changes state or there's a new
512
513
// / PreambleRequest.
513
514
mutable std::condition_variable PreambleCV;
@@ -826,9 +827,10 @@ void ASTWorker::updatePreamble(std::unique_ptr<CompilerInvocation> CI,
826
827
}
827
828
{
828
829
std::lock_guard<std::mutex> Lock (Mutex);
829
- PreambleRequests.push ({std::move (Task), std::move (TaskName),
830
- steady_clock::now (), Context::current ().clone (),
831
- llvm::None, TUScheduler::NoInvalidation, nullptr });
830
+ PreambleRequests.push_back ({std::move (Task), std::move (TaskName),
831
+ steady_clock::now (), Context::current ().clone (),
832
+ llvm::None, llvm::None,
833
+ TUScheduler::NoInvalidation, nullptr });
832
834
}
833
835
PreambleCV.notify_all ();
834
836
RequestsCV.notify_all ();
@@ -1023,9 +1025,34 @@ void ASTWorker::startTask(llvm::StringRef Name,
1023
1025
std::tie (Ctx, Invalidate) = cancelableTask (
1024
1026
/* Reason=*/ static_cast <int >(ErrorCode::ContentModified));
1025
1027
}
1028
+ // Trace the time the request spends in the queue, and the requests that
1029
+ // it's going to wait for.
1030
+ llvm::Optional<Context> QueueCtx;
1031
+ if (trace::enabled ()) {
1032
+ // Tracers that follow threads and need strict nesting will see a tiny
1033
+ // instantaneous event "we're enqueueing", and sometime later it runs.
1034
+ WithContext WC (Ctx.clone ());
1035
+ trace::Span Tracer (" Queued:" + Name);
1036
+ if (Tracer.Args ) {
1037
+ if (CurrentRequest)
1038
+ SPAN_ATTACH (Tracer, " CurrentRequest" , CurrentRequest->Name );
1039
+ llvm::json::Array PreambleRequestsNames;
1040
+ for (const auto &Req : PreambleRequests)
1041
+ PreambleRequestsNames.push_back (Req.Name );
1042
+ SPAN_ATTACH (Tracer, " PreambleRequestsNames" ,
1043
+ std::move (PreambleRequestsNames));
1044
+ llvm::json::Array RequestsNames;
1045
+ for (const auto &Req : Requests)
1046
+ RequestsNames.push_back (Req.Name );
1047
+ SPAN_ATTACH (Tracer, " RequestsNames" , std::move (RequestsNames));
1048
+ }
1049
+ // For tracers that follow contexts, keep the trace span's context alive
1050
+ // until we dequeue the request, so they see the full duration.
1051
+ QueueCtx = Context::current ().clone ();
1052
+ }
1026
1053
Requests.push_back ({std::move (Task), std::string (Name), steady_clock::now (),
1027
- std::move (Ctx), Update, Invalidation ,
1028
- std::move (Invalidate)});
1054
+ std::move (Ctx), std::move (QueueCtx), Update ,
1055
+ Invalidation, std::move (Invalidate)});
1029
1056
}
1030
1057
RequestsCV.notify_all ();
1031
1058
}
@@ -1071,13 +1098,16 @@ void ASTWorker::run() {
1071
1098
// Requests.front(), so prefer them first to preserve LSP order.
1072
1099
if (!PreambleRequests.empty ()) {
1073
1100
CurrentRequest = std::move (PreambleRequests.front ());
1074
- PreambleRequests.pop ();
1101
+ PreambleRequests.pop_front ();
1075
1102
} else {
1076
1103
CurrentRequest = std::move (Requests.front ());
1077
1104
Requests.pop_front ();
1078
1105
}
1079
1106
} // unlock Mutex
1080
1107
1108
+ // Inform tracing that the request was dequeued.
1109
+ CurrentRequest->QueueCtx .reset ();
1110
+
1081
1111
// It is safe to perform reads to CurrentRequest without holding the lock as
1082
1112
// only writer is also this thread.
1083
1113
{
0 commit comments