#include "SourceKit/Support/Tracing.h" #include "swift/Frontend/Frontend.h" #include "llvm/Support/TimeValue.h" #include "llvm/Support/YAMLTraits.h" using namespace SourceKit; using namespace llvm; //----------------------------------------------------------------------------// // General //----------------------------------------------------------------------------// static std::atomic tracing_enabled(false); static std::atomic operation_id(0); //----------------------------------------------------------------------------// // Copnsumers //----------------------------------------------------------------------------// struct TraceConsumerListNode { trace::TraceConsumer *const Consumer; TraceConsumerListNode *Next; }; static std::atomic consumers(nullptr); //----------------------------------------------------------------------------// // Trace commands //----------------------------------------------------------------------------// // Is tracing enabled bool trace::enabled() { return tracing_enabled; } void trace::enable() { tracing_enabled = true; } void trace::disable() { tracing_enabled = false; } // Trace start of perform sema call, returns OpId uint64_t trace::startOpertation(trace::OperationKind OpKind, const trace::SwiftInvocation &Inv, const trace::StringPairs &OpArgs) { auto OpId = ++operation_id; if (trace::enabled()) { auto Node = consumers.load(std::memory_order_acquire); while (Node) { Node->Consumer->opertationStarted(OpId, OpKind, Inv, OpArgs); Node = Node->Next; } } return OpId; } // Operation previously started with startXXX has finished void trace::operationFinished(uint64_t OpId) { if (trace::enabled()) { auto Node = consumers.load(std::memory_order_acquire); while (Node) { Node->Consumer->operationFinished(OpId); Node = Node->Next; } } } // Register trace consumer void trace::registerConsumer(trace::TraceConsumer *Consumer) { TraceConsumerListNode *Node = new TraceConsumerListNode {Consumer, nullptr}; do { Node->Next = consumers.load(std::memory_order_relaxed); } while(!consumers.compare_exchange_weak(Node->Next, Node, std::memory_order_release, std::memory_order_relaxed)); }