[clangd] Changed tracing interfaces

Summary:
EventTracer interface now contains two methods:
- spanEvent for events that have duration,
- instant for events that are instant.

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: klimek, luckygeck, cfe-commits

Differential Revision: https://reviews.llvm.org/D40489

llvm-svn: 320708
This commit is contained in:
Ilya Biryukov 2017-12-14 15:33:38 +00:00
parent c70f1d63f8
commit 12cdb4fd33
2 changed files with 44 additions and 24 deletions

View File

@ -44,10 +44,24 @@ public:
Out.flush();
}
EndEventCallback beginSpan(const Context &Ctx,
llvm::StringRef Name) override {
jsonEvent("B", json::obj{{"name", Name}});
// The callback that will run when event ends.
return [this](json::Expr &&Args) {
jsonEvent("E", json::obj{{"args", std::move(Args)}});
};
}
void instant(const Context &Ctx, llvm::StringRef Name,
json::obj &&Args) override {
jsonEvent("i", json::obj{{"name", Name}, {"args", std::move(Args)}});
}
// Record an event on the current thread. ph, pid, tid, ts are set.
// Contents must be a list of the other JSON key/values.
void event(const Context &Ctx, StringRef Phase,
json::obj &&Contents) override {
void jsonEvent(StringRef Phase, json::obj &&Contents) {
uint64_t TID = get_threadid();
std::lock_guard<std::mutex> Lock(Mu);
// If we haven't already, emit metadata describing this thread.
@ -109,30 +123,26 @@ std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
void log(const Context &Ctx, const Twine &Message) {
if (!T)
return;
T->event(Ctx, "i",
json::obj{
{"name", "Log"},
{"args", json::obj{{"Message", Message.str()}}},
});
T->instant(Ctx, "Log", json::obj{{"Message", Message.str()}});
}
Span::Span(const Context &Ctx, std::string Name) {
Span::Span(const Context &Ctx, llvm::StringRef Name) {
if (!T)
return;
// Clone the context, so that the original Context can be moved.
this->Ctx.emplace(Ctx.clone());
T->event(*this->Ctx, "B", json::obj{{"name", std::move(Name)}});
Callback = T->beginSpan(Ctx, Name);
if (!Callback)
return;
Args = llvm::make_unique<json::obj>();
}
Span::~Span() {
if (!T)
if (!Callback)
return;
if (!Args)
Args = llvm::make_unique<json::obj>();
T->event(*Ctx, "E",
Args ? json::obj{{"args", std::move(*Args)}} : json::obj{});
assert(Args && "Args must be non-null if Callback is defined");
Callback(std::move(*Args));
}
} // namespace trace

View File

@ -19,6 +19,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
#include "Context.h"
#include "Function.h"
#include "JSONExpr.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
@ -28,12 +29,24 @@ namespace clangd {
namespace trace {
/// A consumer of trace events. The events are produced by Spans and trace::log.
/// Implmentations of this interface must be thread-safe.
class EventTracer {
public:
/// A callback executed when an event with duration ends. Args represent data
/// that was attached to the event via SPAN_ATTACH.
using EndEventCallback = UniqueFunction<void(json::obj &&Args)>;
virtual ~EventTracer() = default;
/// Consume a trace event.
virtual void event(const Context &Ctx, llvm::StringRef Phase,
json::obj &&Contents) = 0;
/// Called when event that has a duration starts. The returned callback will
/// be executed when the event ends. \p Name is a descriptive name
/// of the event that was passed to Span constructor.
virtual EndEventCallback beginSpan(const Context &Ctx,
llvm::StringRef Name) = 0;
/// Called for instant events.
virtual void instant(const Context &Ctx, llvm::StringRef Name,
json::obj &&Args) = 0;
};
/// Sets up a global EventTracer that consumes events produced by Span and
@ -50,9 +63,6 @@ public:
///
/// The format is documented here:
/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
///
/// The implementation supports concurrent calls and can be used as a global
/// tracer (i.e., can be put into a global Context).
std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
bool Pretty = false);
@ -67,7 +77,7 @@ void log(const Context &Ctx, const llvm::Twine &Name);
/// SomeJSONExpr is evaluated and copied only if actually needed.
class Span {
public:
Span(const Context &Ctx, std::string Name);
Span(const Context &Ctx, llvm::StringRef Name);
~Span();
/// Returns mutable span metadata if this span is interested.
@ -75,8 +85,8 @@ public:
json::obj *args() { return Args.get(); }
private:
llvm::Optional<Context> Ctx;
std::unique_ptr<json::obj> Args;
EventTracer::EndEventCallback Callback;
};
#define SPAN_ATTACH(S, Name, Expr) \