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 <adeebshihadeh@gmail.com>
pull/22160/head^2
Dean Lee 2021-10-29 18:21:57 +08:00 committed by GitHub
parent 18caf3535b
commit d70e49dca5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 15 deletions

View File

@ -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',

View File

@ -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

View File

@ -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"]

View File

@ -28,16 +28,23 @@ Event::Event(const kj::ArrayPtr<const capnp::word> &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<const capnp::word> 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());

View File

@ -1,6 +1,9 @@
#pragma once
#if __has_include(<memory_resource>)
#define HAS_MEMORY_RESOURCE 1
#include <memory_resource>
#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
};

View File

@ -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();

View File

@ -222,7 +222,8 @@ void Replay::startStream(const Segment *cur_segment) {
camera_server_ = std::make_unique<CameraServer>(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();
}

View File

@ -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;
}
}