diff options
author | 2023-12-19 12:55:14 +0000 | |
---|---|---|
committer | 2023-12-20 12:24:40 +0000 | |
commit | 1ce6b4b817d51e848abce5c7f56ee7294ba36fb6 (patch) | |
tree | 7706b71a02073314c5e12fc2549624f4c8fc2db5 | |
parent | e1e707624d074e4ff395b61de045e7bf55df9b6e (diff) |
Reuse the buffer that holds data to be flushed to file
We use a buffer to generate the trace data in the right format to be
flushed to the file. In streaming mode, we used to allocate and delete
on each flush. Since we need it often, just have one buffer and release
it when the tracing has finished. In non-streaming mode, we used a
global buffer already. We reuse the same buffer but only allocate a
fixed size buffer instead of the user specified size. In streaming mode
the buffer size provided by the user isn't used.
Test: test.py -t 2246
Bug: 259258187
Change-Id: I0710a24ba3ba3fe2534bde0369975cc46ab9c7f4
-rw-r--r-- | runtime/trace.cc | 20 | ||||
-rw-r--r-- | runtime/trace.h | 8 |
2 files changed, 16 insertions, 12 deletions
diff --git a/runtime/trace.cc b/runtime/trace.cc index 9609f00aa3..aa485bef21 100644 --- a/runtime/trace.cc +++ b/runtime/trace.cc @@ -826,8 +826,12 @@ Trace::Trace(File* trace_file, stop_tracing_(false) { CHECK_IMPLIES(trace_file == nullptr, output_mode == TraceOutputMode::kDDMS); + // In streaming mode, we only need a buffer big enough to store data per each + // thread buffer. In non-streaming mode this is specified by the user and we + // stop tracing when the buffer is full. + size_t buf_size = (output_mode == TraceOutputMode::kStreaming) ? kPerThreadBufSize : buffer_size; trace_writer_.reset(new TraceWriter( - trace_file, output_mode, clock_source_, buffer_size, GetClockOverheadNanoSeconds())); + trace_file, output_mode, clock_source_, buf_size, GetClockOverheadNanoSeconds())); } void TraceWriter::FinishTracing(int flags, bool flush_entries) { @@ -1221,17 +1225,15 @@ void TraceWriter::FlushBuffer(uintptr_t* method_trace_entries, // seen method. tracing_lock_ is required to serialize these. MutexLock mu(Thread::Current(), tracing_lock_); size_t current_index; - uint8_t* buffer_ptr = nullptr; - size_t buffer_size; - std::unique_ptr<uint8_t[]> buffer; + uint8_t* buffer_ptr = buf_.get(); + size_t buffer_size = buffer_size_; if (trace_output_mode_ == TraceOutputMode::kStreaming) { - buffer_size = std::max(kMinBufSize, kPerThreadBufSize); - buffer.reset(new uint8_t[buffer_size]); - buffer_ptr = buffer.get(); + // In streaming mode, we flush the data to file each time we flush the per-thread buffer. + // Just reuse the entire buffer. current_index = 0; } else { - buffer_size = buffer_size_; - buffer_ptr = buf_.get(); + // In non-streaming mode we only flush at the end, so retain the earlier data. If the buffer + // is full we don't process any more entries. current_index = cur_offset_; } uint16_t thread_id = GetThreadEncoding(tid); diff --git a/runtime/trace.h b/runtime/trace.h index bbca059e1f..ec9bedce0a 100644 --- a/runtime/trace.h +++ b/runtime/trace.h @@ -246,9 +246,11 @@ class TraceWriter { std::unordered_map<pid_t, uint16_t> thread_id_map_ GUARDED_BY(tracing_lock_); uint16_t current_thread_index_; - // Buffer to store trace data in non-streaming mode. This is only accessed in - // SuspendAll scope to flush the data from all threads into this buffer. This - // is only used in non-streaming mode + // Buffer used when generating trace data from the raw entries. + // In streaming mode, the trace data is flushed to file when the per-thread buffer gets full. + // In non-streaming mode, this data is flushed at the end of tracing. If the buffer gets full + // we stop tracing and following trace events are ignored. The size of this buffer is + // specified by the user in non-streaming mode. std::unique_ptr<uint8_t[]> buf_; // The cur_offset_ into the buf_. Accessed only in SuspendAll scope when flushing data from the |