GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/tracing/agent.h Lines: 37 37 100.0 %
Date: 2019-09-23 22:30:09 Branches: 11 18 61.1 %

Line Branch Exec Source
1
#ifndef SRC_TRACING_AGENT_H_
2
#define SRC_TRACING_AGENT_H_
3
4
#include "libplatform/v8-tracing.h"
5
#include "uv.h"
6
#include "v8.h"
7
#include "util.h"
8
#include "node_mutex.h"
9
10
#include <list>
11
#include <set>
12
#include <string>
13
#include <unordered_map>
14
15
namespace node {
16
namespace tracing {
17
18
using v8::platform::tracing::TraceConfig;
19
using v8::platform::tracing::TraceObject;
20
21
class Agent;
22
23
72
class AsyncTraceWriter {
24
 public:
25
72
  virtual ~AsyncTraceWriter() = default;
26
  virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
27
  virtual void Flush(bool blocking) = 0;
28
2
  virtual void InitializeOnThread(uv_loop_t* loop) {}
29
};
30
31
9978
class TracingController : public v8::platform::tracing::TracingController {
32
 public:
33
4989
  TracingController() : v8::platform::tracing::TracingController() {}
34
35
2644
  int64_t CurrentTimestampMicroseconds() override {
36
2644
    return uv_hrtime() / 1000;
37
  }
38
  void AddMetadataEvent(
39
      const unsigned char* category_group_enabled,
40
      const char* name,
41
      int num_args,
42
      const char** arg_names,
43
      const unsigned char* arg_types,
44
      const uint64_t* arg_values,
45
      std::unique_ptr<v8::ConvertableToTraceFormat>* convertable_values,
46
      unsigned int flags);
47
};
48
49
class AgentWriterHandle {
50
 public:
51
10492
  inline AgentWriterHandle() = default;
52
15145
  inline ~AgentWriterHandle() { reset(); }
53
54
  inline AgentWriterHandle(AgentWriterHandle&& other);
55
  inline AgentWriterHandle& operator=(AgentWriterHandle&& other);
56
3
  inline bool empty() const { return agent_ == nullptr; }
57
  inline void reset();
58
59
  inline void Enable(const std::set<std::string>& categories);
60
  inline void Disable(const std::set<std::string>& categories);
61
62
  inline bool IsDefaultHandle();
63
64
19
  inline Agent* agent() { return agent_; }
65
66
  inline v8::TracingController* GetTracingController();
67
68
  AgentWriterHandle(const AgentWriterHandle& other) = delete;
69
  AgentWriterHandle& operator=(const AgentWriterHandle& other) = delete;
70
71
 private:
72
5062
  inline AgentWriterHandle(Agent* agent, int id) : agent_(agent), id_(id) {}
73
74
  Agent* agent_ = nullptr;
75
  int id_;
76
77
  friend class Agent;
78
};
79
80
class Agent {
81
 public:
82
  Agent();
83
  ~Agent();
84
85
1493464
  TracingController* GetTracingController() {
86
1493464
    TracingController* controller = tracing_controller_.get();
87
1493577
    CHECK_NOT_NULL(controller);
88
1493577
    return controller;
89
  }
90
91
  enum UseDefaultCategoryMode {
92
    kUseDefaultCategories,
93
    kIgnoreDefaultCategories
94
  };
95
96
  // Destroying the handle disconnects the client
97
  AgentWriterHandle AddClient(const std::set<std::string>& categories,
98
                              std::unique_ptr<AsyncTraceWriter> writer,
99
                              enum UseDefaultCategoryMode mode);
100
  // A handle that is only used for managing the default categories
101
  // (which can then implicitly be used through using `USE_DEFAULT_CATEGORIES`
102
  // when adding a client later).
103
  AgentWriterHandle DefaultHandle();
104
105
  // Returns a comma-separated list of enabled categories.
106
  std::string GetEnabledCategories() const;
107
108
  // Writes to all writers registered through AddClient().
109
  void AppendTraceEvent(TraceObject* trace_event);
110
111
  void AddMetadataEvent(std::unique_ptr<TraceObject> event);
112
  // Flushes all writers registered through AddClient().
113
  void Flush(bool blocking);
114
115
  TraceConfig* CreateTraceConfig() const;
116
117
 private:
118
  friend class AgentWriterHandle;
119
120
  void InitializeWritersOnThread();
121
122
  void Start();
123
  void StopTracing();
124
  void Disconnect(int client);
125
126
  void Enable(int id, const std::set<std::string>& categories);
127
  void Disable(int id, const std::set<std::string>& categories);
128
129
  uv_thread_t thread_;
130
  uv_loop_t tracing_loop_;
131
132
  bool started_ = false;
133
  class ScopedSuspendTracing;
134
135
  // Each individual Writer has one id.
136
  int next_writer_id_ = 1;
137
  enum { kDefaultHandleId = -1 };
138
  // These maps store the original arguments to AddClient(), by id.
139
  std::unordered_map<int, std::multiset<std::string>> categories_;
140
  std::unordered_map<int, std::unique_ptr<AsyncTraceWriter>> writers_;
141
  std::unique_ptr<TracingController> tracing_controller_;
142
143
  // Variables related to initializing per-event-loop properties of individual
144
  // writers, such as libuv handles.
145
  Mutex initialize_writer_mutex_;
146
  ConditionVariable initialize_writer_condvar_;
147
  uv_async_t initialize_writer_async_;
148
  std::set<AsyncTraceWriter*> to_be_initialized_;
149
150
  Mutex metadata_events_mutex_;
151
  std::list<std::unique_ptr<TraceObject>> metadata_events_;
152
};
153
154
30229
void AgentWriterHandle::reset() {
155
30229
  if (agent_ != nullptr)
156
5061
    agent_->Disconnect(id_);
157
30229
  agent_ = nullptr;
158
30229
}
159
160
5061
AgentWriterHandle& AgentWriterHandle::operator=(AgentWriterHandle&& other) {
161
5061
  reset();
162
5061
  agent_ = other.agent_;
163
5061
  id_ = other.id_;
164
5061
  other.agent_ = nullptr;
165
5061
  return *this;
166
}
167
168
AgentWriterHandle::AgentWriterHandle(AgentWriterHandle&& other) {
169
  *this = std::move(other);
170
}
171
172
20
void AgentWriterHandle::Enable(const std::set<std::string>& categories) {
173
20
  if (agent_ != nullptr) agent_->Enable(id_, categories);
174
20
}
175
176
6
void AgentWriterHandle::Disable(const std::set<std::string>& categories) {
177
6
  if (agent_ != nullptr) agent_->Disable(id_, categories);
178
6
}
179
180
87
bool AgentWriterHandle::IsDefaultHandle() {
181

87
  return agent_ != nullptr && id_ == Agent::kDefaultHandleId;
182
}
183
184
9982
inline v8::TracingController* AgentWriterHandle::GetTracingController() {
185
9982
  return agent_ != nullptr ? agent_->GetTracingController() : nullptr;
186
}
187
188
}  // namespace tracing
189
}  // namespace node
190
191
#endif  // SRC_TRACING_AGENT_H_