diff --git a/selfdrive/ui/replay/logreader.cc b/selfdrive/ui/replay/logreader.cc index d4ef8e5c00..d14ea9d4da 100644 --- a/selfdrive/ui/replay/logreader.cc +++ b/selfdrive/ui/replay/logreader.cc @@ -27,8 +27,17 @@ Event::Event(const kj::ArrayPtr &amsg, bool frame) : reader(a // class LogReader +LogReader::LogReader(size_t memory_pool_block_size) { + const size_t buf_size = sizeof(Event) * memory_pool_block_size; + pool_buffer_ = ::operator new(buf_size); + mbr_ = new std::pmr::monotonic_buffer_resource(pool_buffer_, buf_size); + + events.reserve(memory_pool_block_size); +} + LogReader::~LogReader() { - for (auto e : events) delete e; + delete mbr_; + ::operator delete(pool_buffer_); } bool LogReader::load(const std::string &file) { @@ -47,19 +56,19 @@ bool LogReader::load(const std::string &file) { kj::ArrayPtr words((const capnp::word *)raw_.data(), raw_.size() / sizeof(capnp::word)); while (words.size() > 0) { try { - std::unique_ptr evt = std::make_unique(words); + Event *evt = new (mbr_) Event(words); // Add encodeIdx packet again as a frame packet for the video stream if (evt->which == cereal::Event::ROAD_ENCODE_IDX || evt->which == cereal::Event::DRIVER_ENCODE_IDX || evt->which == cereal::Event::WIDE_ROAD_ENCODE_IDX) { - std::unique_ptr frame_evt = std::make_unique(words, true); - events.push_back(frame_evt.release()); + Event *frame_evt = new (mbr_) Event(words, true); + events.push_back(frame_evt); } words = kj::arrayPtr(evt->reader.getEnd(), words.end()); - events.push_back(evt.release()); + events.push_back(evt); } catch (const kj::Exception &e) { return false; } diff --git a/selfdrive/ui/replay/logreader.h b/selfdrive/ui/replay/logreader.h index 348dcfd384..79031441ee 100644 --- a/selfdrive/ui/replay/logreader.h +++ b/selfdrive/ui/replay/logreader.h @@ -1,11 +1,13 @@ #pragma once -#include +#include + #include "cereal/gen/cpp/log.capnp.h" #include "selfdrive/camerad/cameras/camera_common.h" const CameraType ALL_CAMERAS[] = {RoadCam, DriverCam, WideRoadCam}; const int MAX_CAMERAS = std::size(ALL_CAMERAS); +const int DEFAULT_EVENT_MEMORY_POOL_BLOCK_SIZE = 65000; class Event { public: @@ -23,6 +25,13 @@ public: } }; + void *operator new(size_t size, std::pmr::monotonic_buffer_resource *mbr) { + return mbr->allocate(size); + } + void operator delete(void *ptr) { + // No-op. memory used by EventMemoryPool increases monotonically until the logReader is destroyed. + } + uint64_t mono_time; cereal::Event::Which which; cereal::Event::Reader event; @@ -33,7 +42,7 @@ public: class LogReader { public: - LogReader() = default; + LogReader(size_t memory_pool_block_size = DEFAULT_EVENT_MEMORY_POOL_BLOCK_SIZE); ~LogReader(); bool load(const std::string &file); @@ -41,4 +50,6 @@ public: private: std::string raw_; + std::pmr::monotonic_buffer_resource *mbr_ = nullptr; + void *pool_buffer_ = nullptr; };