simpleperf: Delay processing ETM data until the buffer is half full

When using --decode-etm, the main thread is busy processing ETM data
and can miss flushing ETM data. To fix this, we can delay processing
ETM data after recording.

This patch triggers ETM data processing when the buffer is at least
half full. In the default configuration, the buffer is large enough
to hold ETM data for several seconds. So effectively, this delays
processing ETM data after recording.

Bug: 336375740
Test: run simpleperf_unit_test
Change-Id: Ib892aeea402773b1cab785f2c14886bb9f96d851
diff --git a/simpleperf/RecordReadThread.cpp b/simpleperf/RecordReadThread.cpp
index 2ab6127..2d034bc 100644
--- a/simpleperf/RecordReadThread.cpp
+++ b/simpleperf/RecordReadThread.cpp
@@ -408,6 +408,7 @@
             success = false;
             break;
           }
+          has_etm_events_ = true;
         }
         cpu_map[fd->Cpu()] = fd;
       } else {
@@ -620,6 +621,9 @@
 }
 
 void RecordReadThread::ReadAuxDataFromKernelBuffer(bool* has_data) {
+  if (!has_etm_events_) {
+    return;
+  }
   for (auto& reader : kernel_record_readers_) {
     EventFd* event_fd = reader.GetEventFd();
     if (event_fd->HasAuxBuffer()) {
@@ -659,6 +663,14 @@
 }
 
 bool RecordReadThread::SendDataNotificationToMainThread() {
+  if (has_etm_events_) {
+    // For ETM recording, the default buffer size is large enough to hold ETM data for several
+    // seconds. To reduce impact of processing ETM data (especially when --decode-etm is used),
+    // delay processing ETM data until the buffer is half full.
+    if (record_buffer_.GetFreeSize() >= record_buffer_.size() / 2) {
+      return true;
+    }
+  }
   if (!has_data_notification_.load(std::memory_order_relaxed)) {
     has_data_notification_ = true;
     char unused = 0;
diff --git a/simpleperf/RecordReadThread.h b/simpleperf/RecordReadThread.h
index c104b08..893f823 100644
--- a/simpleperf/RecordReadThread.h
+++ b/simpleperf/RecordReadThread.h
@@ -211,6 +211,7 @@
   std::unique_ptr<std::thread> read_thread_;
   std::vector<KernelRecordReader> kernel_record_readers_;
   pid_t exclude_pid_ = -1;
+  bool has_etm_events_ = false;
 
   std::unordered_set<EventFd*> event_fds_disabled_by_kernel_;