Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/a2a3/platform/src/host/tensor_dump_collector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,29 @@ int TensorDumpCollector::finalize(DumpUnregisterCallback unregister_cb, const Du
// Stop mgmt + collector threads if the caller didn't already (idempotent).
stop();

// ProfilerBase::stop() only joins the mgmt + poll threads. The writer
// thread is otherwise torn down solely by export_dump_files(), so any path
// that skips export — e.g. run() bailing on a device error before its
// collector-teardown block — would leak it: left blocked on write_cv_ with
// writer_done_ == false while writer_thread_ stays joinable, which trips
// std::terminate when the collector is destroyed or re-run. finalize() is
// reached via run()'s perf_cleanup guard on every exit path, so join the
// writer here too. Idempotent: export_dump_files() clears writer_started_
// on the success path, making this a no-op.
if (writer_started_ && writer_thread_.joinable()) {
writer_done_.store(true);
write_cv_.notify_one();
writer_thread_.join();
}
Comment thread
ChaoZheng109 marked this conversation as resolved.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// The writer thread opens bin_file_ in start_writer_thread_once() and it is
// otherwise closed only by export_dump_files(). Close it here too so an
// export-skipping path does not leave it open — a stale-open stream makes
// the next run's bin_file_.open() set failbit. Guarded for idempotency.
if (bin_file_.is_open()) {
bin_file_.close();
}

// DumpMetaBuffers appear in multiple lists (per-thread free_queues,
// recycled pool); dedup so each dev_ptr funnels through the shared
// ProfilerBase RAII helper exactly once.
Expand Down
23 changes: 23 additions & 0 deletions src/a5/platform/src/host/tensor_dump_collector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,29 @@ int TensorDumpCollector::finalize(DumpUnregisterCallback unregister_cb, const Du
// Stop mgmt + collector threads if the caller didn't already (idempotent).
stop();

// ProfilerBase::stop() only joins the mgmt + poll threads. The writer
// thread is otherwise torn down solely by export_dump_files(), so any path
// that skips export — e.g. run() bailing on a device error before its
// collector-teardown block — would leak it: left blocked on write_cv_ with
// writer_done_ == false while writer_thread_ stays joinable, which trips
// std::terminate when the collector is destroyed or re-run. finalize() is
// reached via run()'s perf_cleanup guard on every exit path, so join the
// writer here too. Idempotent: export_dump_files() clears writer_started_
// on the success path, making this a no-op.
if (writer_started_ && writer_thread_.joinable()) {
writer_done_.store(true);
write_cv_.notify_one();
writer_thread_.join();
}
Comment thread
ChaoZheng109 marked this conversation as resolved.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// The writer thread opens bin_file_ in start_writer_thread_once() and it is
// otherwise closed only by export_dump_files(). Close it here too so an
// export-skipping path does not leave it open — a stale-open stream makes
// the next run's bin_file_.open() set failbit. Guarded for idempotency.
if (bin_file_.is_open()) {
bin_file_.close();
}

auto release_dev = [&](void *p) {
release_one_buffer(p, unregister_cb, free_cb);
};
Expand Down
Loading