1 #ifndef SRC_TRACING_NODE_TRACE_BUFFER_H_ 2 #define SRC_TRACING_NODE_TRACE_BUFFER_H_ 3 4 #include "tracing/agent.h" 5 #include "node_mutex.h" 6 #include "libplatform/v8-tracing.h" 7 8 #include <atomic> 9 10 namespace node { 11 namespace tracing { 12 13 using v8::platform::tracing::TraceBuffer; 14 using v8::platform::tracing::TraceBufferChunk; 15 using v8::platform::tracing::TraceObject; 16 17 // forward declaration 18 class NodeTraceBuffer; 19 20 class InternalTraceBuffer { 21 public: 22 InternalTraceBuffer(size_t max_chunks, uint32_t id, Agent* agent); 23 24 TraceObject* AddTraceEvent(uint64_t* handle); 25 TraceObject* GetEventByHandle(uint64_t handle); 26 void Flush(bool blocking); IsFull()27 bool IsFull() const { 28 return total_chunks_ == max_chunks_ && chunks_[total_chunks_ - 1]->IsFull(); 29 } IsFlushing()30 bool IsFlushing() const { 31 return flushing_; 32 } 33 34 private: 35 uint64_t MakeHandle(size_t chunk_index, uint32_t chunk_seq, 36 size_t event_index) const; 37 void ExtractHandle(uint64_t handle, uint32_t* buffer_id, size_t* chunk_index, 38 uint32_t* chunk_seq, size_t* event_index) const; Capacity()39 size_t Capacity() const { return max_chunks_ * TraceBufferChunk::kChunkSize; } 40 41 Mutex mutex_; 42 bool flushing_; 43 size_t max_chunks_; 44 Agent* agent_; 45 std::vector<std::unique_ptr<TraceBufferChunk>> chunks_; 46 size_t total_chunks_ = 0; 47 uint32_t current_chunk_seq_ = 1; 48 uint32_t id_; 49 }; 50 51 class NodeTraceBuffer : public TraceBuffer { 52 public: 53 NodeTraceBuffer(size_t max_chunks, Agent* agent, uv_loop_t* tracing_loop); 54 ~NodeTraceBuffer() override; 55 56 TraceObject* AddTraceEvent(uint64_t* handle) override; 57 TraceObject* GetEventByHandle(uint64_t handle) override; 58 bool Flush() override; 59 60 static const size_t kBufferChunks = 1024; 61 62 private: 63 bool TryLoadAvailableBuffer(); 64 static void NonBlockingFlushSignalCb(uv_async_t* signal); 65 static void ExitSignalCb(uv_async_t* signal); 66 67 uv_loop_t* tracing_loop_; 68 uv_async_t flush_signal_; 69 uv_async_t exit_signal_; 70 bool exited_ = false; 71 // Used exclusively for exit logic. 72 Mutex exit_mutex_; 73 // Used to wait until async handles have been closed. 74 ConditionVariable exit_cond_; 75 std::atomic<InternalTraceBuffer*> current_buf_; 76 InternalTraceBuffer buffer1_; 77 InternalTraceBuffer buffer2_; 78 }; 79 80 } // namespace tracing 81 } // namespace node 82 83 #endif // SRC_TRACING_NODE_TRACE_BUFFER_H_ 84