12 #include "llvm/ADT/DenseSet.h" 13 #include "llvm/ADT/ScopeExit.h" 14 #include "llvm/Support/Chrono.h" 15 #include "llvm/Support/FormatProviders.h" 16 #include "llvm/Support/FormatVariadic.h" 17 #include "llvm/Support/Threading.h" 30 JSONTracer(llvm::raw_ostream &OS,
bool Pretty)
31 : Out(OS, Pretty ? 2 : 0), Start(std::chrono::system_clock::now()) {
35 Out.attribute(
"displayTimeUnit",
"ns");
36 Out.attributeBegin(
"traceEvents");
38 rawEvent(
"M", llvm::json::Object{
39 {
"name",
"process_name"},
40 {
"args", llvm::json::Object{{
"name",
"clangd"}}},
53 Context beginSpan(llvm::StringRef
Name, llvm::json::Object *Args)
override {
55 SpanKey, llvm::make_unique<JSONSpan>(
this, Name, Args));
62 void endSpan()
override {
66 void instant(llvm::StringRef Name, llvm::json::Object &&Args)
override {
67 captureThreadMetadata();
69 llvm::json::Object{{
"name", Name}, {
"args", std::move(Args)}});
74 void jsonEvent(llvm::StringRef Phase, llvm::json::Object &&
Contents,
75 uint64_t TID = llvm::get_threadid(),
double Timestamp = 0) {
76 Contents[
"ts"] = Timestamp ? Timestamp : timestamp();
78 std::lock_guard<std::mutex> Lock(Mu);
85 JSONSpan(JSONTracer *Tracer, llvm::StringRef Name, llvm::json::Object *Args)
86 : StartTime(Tracer->timestamp()), EndTime(0), Name(Name),
87 TID(llvm::get_threadid()), Tracer(Tracer), Args(Args) {
89 Tracer->captureThreadMetadata();
97 if (Parent && *Parent && (*Parent)->TID != TID) {
100 double OriginTime = (*Parent)->EndTime;
102 OriginTime = (*Parent)->StartTime;
104 auto FlowID = nextID();
107 llvm::json::Object{{
"id", FlowID},
108 {
"name",
"Context crosses threads"},
110 (*Parent)->TID, (*Parent)->StartTime);
113 llvm::json::Object{{
"id", FlowID},
115 {
"name",
"Context crosses threads"},
123 Tracer->jsonEvent(
"X",
124 llvm::json::Object{{
"name", std::move(Name)},
125 {
"args", std::move(*Args)},
126 {
"dur", EndTime - StartTime}},
131 void markEnded() { EndTime = Tracer->timestamp(); }
134 static int64_t nextID() {
135 static std::atomic<int64_t> Next = {0};
140 std::atomic<double> EndTime;
144 llvm::json::Object *Args;
150 void rawEvent(llvm::StringRef Phase,
151 const llvm::json::Object &
Event) {
154 Out.attribute(
"pid", 0);
155 Out.attribute(
"ph", Phase);
156 for (
const auto& KV : Event)
157 Out.attribute(KV.first, KV.second);
162 void captureThreadMetadata() {
163 uint64_t TID = llvm::get_threadid();
164 std::lock_guard<std::mutex> Lock(Mu);
165 if (ThreadsWithMD.insert(TID).second) {
166 llvm::SmallString<32> Name;
167 llvm::get_thread_name(Name);
169 rawEvent(
"M", llvm::json::Object{
170 {
"tid", int64_t(TID)},
171 {
"name",
"thread_name"},
172 {
"args", llvm::json::Object{{
"name", Name}}},
179 using namespace std::chrono;
180 return duration<double, std::micro>(system_clock::now() - Start).count();
184 llvm::json::OStream Out ;
185 llvm::DenseSet<uint64_t> ThreadsWithMD ;
186 const llvm::sys::TimePoint<> Start;
195 assert(!T &&
"Resetting global tracer is not allowed.");
203 return llvm::make_unique<JSONTracer>(OS, Pretty);
209 T->instant(
"Log", llvm::json::Object{{
"Message", Message.str()}});
217 return T->beginSpan(Name.isSingleStringRef() ? Name.getSingleStringRef()
218 : llvm::StringRef(Name.str()),
226 : Args(T ? new
llvm::json::
Object() : nullptr),
Session(EventTracer &Tracer)
Some operations such as code completion produce a set of candidates.
An Event<T> allows events of type T to be broadcast to listeners.
constexpr llvm::StringLiteral Message
Values in a Context are indexed by typed keys.
const Type * get(const Key< Type > &Key) const
Get data stored for a typed Key.
Context clone() const
Clone this context object.
static const Context & current()
Returns the context for the current thread, creating it if needed.
A context is an immutable container for per-request data that must be propagated through layers that ...
const Type & getExisting(const Key< Type > &Key) const
A helper to get a reference to a Key that must exist in the map.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void log(const llvm::Twine &Message)
Records a single instant event, associated with the current thread.
Context derive(const Key< Type > &Key, typename std::decay< Type >::type Value) const &
Derives a child context It is safe to move or destroy a parent context after calling derive()...
std::unique_ptr< EventTracer > createJSONTracer(llvm::raw_ostream &OS, bool Pretty)
Create an instance of EventTracer that produces an output in the Trace Event format supported by Chro...
WithContextValue extends Context::current() with a single value.
static Context makeSpanContext(llvm::Twine Name, llvm::json::Object *Args)
A consumer of trace events.