From d70e49dca5687c3a26d4b67a7a3dbf04c224e04f Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 29 Oct 2021 18:21:57 +0800 Subject: [PATCH] replay: build on devices (#22632) * there is no QThread::create on device * add files to files_common * modify SConscript * no memory_resouce on device * #define HAS_MEMORY_RESOURCE * fix hangs on shutdown * build on device with the --extra flag * delete later * setup -> extras Co-authored-by: Adeeb Shihadeh --- SConstruct | 4 ++-- release/files_common | 4 ++-- selfdrive/ui/SConscript | 6 +++--- selfdrive/ui/replay/logreader.cc | 22 ++++++++++++++++++---- selfdrive/ui/replay/logreader.h | 7 +++++++ selfdrive/ui/replay/main.cc | 3 ++- selfdrive/ui/replay/replay.cc | 3 ++- selfdrive/ui/replay/route.cc | 9 +++++++-- 8 files changed, 43 insertions(+), 15 deletions(-) diff --git a/SConstruct b/SConstruct index 8b682847a..94369e4a2 100644 --- a/SConstruct +++ b/SConstruct @@ -13,9 +13,9 @@ AddOption('--test', action='store_true', help='build test files') -AddOption('--setup', +AddOption('--extras', action='store_true', - help='build setup and installer files') + help='build misc extras, like setup and installer files') AddOption('--kaitai', action='store_true', diff --git a/release/files_common b/release/files_common index ef7856e88..7a4d7bd8d 100644 --- a/release/files_common +++ b/release/files_common @@ -351,8 +351,8 @@ selfdrive/ui/qt/widgets/*.h selfdrive/ui/qt/spinner_aarch64 selfdrive/ui/qt/text_aarch64 -selfdrive/ui/replay/framereader.cc -selfdrive/ui/replay/framereader.h +selfdrive/ui/replay/*.cc +selfdrive/ui/replay/*.h selfdrive/camerad/SConscript selfdrive/camerad/main.cc diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index eeb70a006..6fa32a78c 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -61,13 +61,13 @@ qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs) # setup and factory resetter -if arch != 'aarch64' and GetOption('setup'): +if arch != 'aarch64' and GetOption('extras'): qt_env.Program("qt/setup/reset", ["qt/setup/reset.cc"], LIBS=qt_libs) qt_env.Program("qt/setup/setup", ["qt/setup/setup.cc", asset_obj], LIBS=qt_libs + ['curl', 'common', 'json11']) -if GetOption('setup'): +if GetOption('extras'): # buidl updater UI qt_env.Program("qt/setup/updater", ["qt/setup/updater.cc", asset_obj], LIBS=qt_libs) @@ -107,7 +107,7 @@ if GetOption('setup'): # build headless replay -if arch in ['x86_64', 'Darwin'] and os.path.exists(Dir("#tools/").get_abspath()): +if arch in ['x86_64', 'Darwin'] or GetOption('extras'): qt_env['CXXFLAGS'] += ["-Wno-deprecated-declarations"] replay_lib_src = ["replay/replay.cc", "replay/camera.cc", "replay/logreader.cc", "replay/framereader.cc", "replay/route.cc", "replay/util.cc"] diff --git a/selfdrive/ui/replay/logreader.cc b/selfdrive/ui/replay/logreader.cc index d14ea9d4d..04c42bc1a 100644 --- a/selfdrive/ui/replay/logreader.cc +++ b/selfdrive/ui/replay/logreader.cc @@ -28,16 +28,23 @@ Event::Event(const kj::ArrayPtr &amsg, bool frame) : reader(a // class LogReader LogReader::LogReader(size_t memory_pool_block_size) { +#ifdef HAS_MEMORY_RESOURCE 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); - +#endif events.reserve(memory_pool_block_size); } LogReader::~LogReader() { +#ifdef HAS_MEMORY_RESOURCE delete mbr_; ::operator delete(pool_buffer_); +#else + for (Event *e : events) { + delete e; + } +#endif } bool LogReader::load(const std::string &file) { @@ -56,15 +63,22 @@ 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 { +#ifdef HAS_MEMORY_RESOURCE Event *evt = new (mbr_) Event(words); +#else + Event *evt = new Event(words); +#endif // 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) { - - Event *frame_evt = new (mbr_) Event(words, true); - events.push_back(frame_evt); +#ifdef HAS_MEMORY_RESOURCE + Event *frame_evt = new (mbr_) Event(words, true); +#else + Event *frame_evt = new Event(words, true); +#endif + events.push_back(frame_evt); } words = kj::arrayPtr(evt->reader.getEnd(), words.end()); diff --git a/selfdrive/ui/replay/logreader.h b/selfdrive/ui/replay/logreader.h index 79031441e..0fb371132 100644 --- a/selfdrive/ui/replay/logreader.h +++ b/selfdrive/ui/replay/logreader.h @@ -1,6 +1,9 @@ #pragma once +#if __has_include() +#define HAS_MEMORY_RESOURCE 1 #include +#endif #include "cereal/gen/cpp/log.capnp.h" #include "selfdrive/camerad/cameras/camera_common.h" @@ -25,12 +28,14 @@ public: } }; +#if HAS_MEMORY_RESOURCE 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. } +#endif uint64_t mono_time; cereal::Event::Which which; @@ -50,6 +55,8 @@ public: private: std::string raw_; +#ifdef HAS_MEMORY_RESOURCE std::pmr::monotonic_buffer_resource *mbr_ = nullptr; void *pool_buffer_ = nullptr; +#endif }; diff --git a/selfdrive/ui/replay/main.cc b/selfdrive/ui/replay/main.cc index 2d44975e4..2f417fc6a 100644 --- a/selfdrive/ui/replay/main.cc +++ b/selfdrive/ui/replay/main.cc @@ -115,7 +115,8 @@ int main(int argc, char *argv[]){ } replay->start(parser.value("start").toInt()); // start keyboard control thread - QThread *t = QThread::create(keyboardThread, replay); + QThread *t = new QThread(); + QObject::connect(t, &QThread::started, [=]() { keyboardThread(replay); }); QObject::connect(t, &QThread::finished, t, &QThread::deleteLater); t->start(); diff --git a/selfdrive/ui/replay/replay.cc b/selfdrive/ui/replay/replay.cc index 8983ef5b1..67806f556 100644 --- a/selfdrive/ui/replay/replay.cc +++ b/selfdrive/ui/replay/replay.cc @@ -222,7 +222,8 @@ void Replay::startStream(const Segment *cur_segment) { camera_server_ = std::make_unique(camera_size); // start stream thread - stream_thread_ = QThread::create(&Replay::stream, this); + stream_thread_ = new QThread(); + QObject::connect(stream_thread_, &QThread::started, [=]() { stream(); }); QObject::connect(stream_thread_, &QThread::finished, stream_thread_, &QThread::deleteLater); stream_thread_->start(); } diff --git a/selfdrive/ui/replay/route.cc b/selfdrive/ui/replay/route.cc index 71be470ca..6338fd16e 100644 --- a/selfdrive/ui/replay/route.cc +++ b/selfdrive/ui/replay/route.cc @@ -100,7 +100,9 @@ Segment::Segment(int n, const SegmentFile &files, bool load_dcam, bool load_ecam for (int i = 0; i < std::size(file_list); i++) { if (!file_list[i].isEmpty()) { loading_++; - loading_threads_.emplace_back(QThread::create(&Segment::loadFile, this, i, file_list[i].toStdString()))->start(); + QThread *t = new QThread(); + QObject::connect(t, &QThread::started, [=]() { loadFile(i, file_list[i].toStdString()); }); + loading_threads_.emplace_back(t)->start(); } } } @@ -108,7 +110,10 @@ Segment::Segment(int n, const SegmentFile &files, bool load_dcam, bool load_ecam Segment::~Segment() { aborting_ = true; for (QThread *t : loading_threads_) { - if (t->isRunning()) t->wait(); + if (t->isRunning()) { + t->quit(); + t->wait(); + } delete t; } }