diff --git a/linux-perf-listener.cc b/linux-perf-listener.cc index 5f50f64..75a4f1e 100644 --- a/linux-perf-listener.cc +++ b/linux-perf-listener.cc @@ -1,17 +1,39 @@ #include +#include +#include +#include +#include +#include +#include #include "linux-perf.h" namespace node { +void write_to_file(LinuxPerfHandler* handler) { + + while(handler->IsAlive()) { + std::vector arr = handler->GetBufferElements(100); + if (arr.size() > 0 ) { + for(uint i = 0; i < arr.size(); i++) { + *(handler->GetFile()) << arr[i]; + } + } + std::chrono::milliseconds(1000); + } +} + LinuxPerfHandler::LinuxPerfHandler(v8::Isolate* isolate) : v8::CodeEventHandler(isolate) { // TODO(mmarchini):: ideally this should be handled in another thread. auto pid = static_cast(uv_os_getpid()); mapFile.open("/tmp/perf-" + std::to_string(pid) + ".map"); + t = std::thread(write_to_file, this); } LinuxPerfHandler::~LinuxPerfHandler() { + alive = false; + t.join(); mapFile.close(); } @@ -36,10 +58,16 @@ std::string LinuxPerfHandler::FormatName(v8::CodeEvent* code_event) { } void LinuxPerfHandler::Handle(v8::CodeEvent* code_event) { - mapFile << std::hex << code_event->GetCodeStartAddress() << " " + // std::cout << "Handling event" << std::endl; + codeEventStream << std::hex << code_event->GetCodeStartAddress() << " " << std::hex << code_event->GetCodeSize() << " " << v8::CodeEvent::GetCodeEventTypeName(code_event->GetCodeType()) << ":" << FormatName(code_event) << std::endl; + + std::lock_guard lock(mutex_); + buffer.push(codeEventStream.str()); + codeEventStream.str(""); } + } diff --git a/linux-perf.h b/linux-perf.h index b76bcd2..512b6da 100644 --- a/linux-perf.h +++ b/linux-perf.h @@ -5,7 +5,12 @@ #include #include #include - +#include +#include +#include +#include +#include +#include namespace node { @@ -14,11 +19,36 @@ class LinuxPerfHandler : public v8::CodeEventHandler { explicit LinuxPerfHandler(v8::Isolate* isolate); ~LinuxPerfHandler() override; - void Handle(v8::CodeEvent* code_event) override; + + std::vector GetBufferElements(int n) { + int count = 0; + std::vector values; + std::lock_guard lock(mutex_); + while(count < n && !buffer.empty()) { + values.push_back(buffer.front()); + buffer.pop(); + count++; + } + return values; + } + + bool IsAlive() { + return alive; + } + + std::ofstream* GetFile() { + return &mapFile; + } + private: + bool alive = true; + std::thread t; std::ofstream mapFile; + std::queue buffer; + std::stringstream codeEventStream; std::string FormatName(v8::CodeEvent* code_event); + std::mutex mutex_; }; class LinuxPerf : public Nan::ObjectWrap { diff --git a/package-lock.json b/package-lock.json index ce27ce8..90fff77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "linux-perf", - "version": "0.1.0", + "version": "0.1.1", "lockfileVersion": 1, "requires": true, "dependencies": {