1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2019-2021 Collabora, Ltd. 3bf215546Sopenharmony_ci * Author: Antonio Caggiano <antonio.caggiano@collabora.com> 4bf215546Sopenharmony_ci * Author: Rohan Garg <rohan.garg@collabora.com> 5bf215546Sopenharmony_ci * Author: Robert Beckett <bob.beckett@collabora.com> 6bf215546Sopenharmony_ci * Author: Corentin Noël <corentin.noel@collabora.com> 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 9bf215546Sopenharmony_ci */ 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci#include "pps_datasource.h" 12bf215546Sopenharmony_ci#include "pps_driver.h" 13bf215546Sopenharmony_ci 14bf215546Sopenharmony_ci#include <condition_variable> 15bf215546Sopenharmony_ci#include <thread> 16bf215546Sopenharmony_ci#include <variant> 17bf215546Sopenharmony_ci 18bf215546Sopenharmony_ci// Minimum supported sampling period in nanoseconds 19bf215546Sopenharmony_ci#define MIN_SAMPLING_PERIOD_NS 50000 20bf215546Sopenharmony_ci 21bf215546Sopenharmony_ci#define CORRELATION_TIMESTAMP_PERIOD (1000000000ull) 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_cinamespace pps 24bf215546Sopenharmony_ci{ 25bf215546Sopenharmony_cistatic std::string driver_name; 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci/// Synchronize access to started_cv and started 28bf215546Sopenharmony_cistatic std::mutex started_m; 29bf215546Sopenharmony_cistatic std::condition_variable started_cv; 30bf215546Sopenharmony_cistatic bool started = false; 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cifloat ms(const std::chrono::nanoseconds &t) 33bf215546Sopenharmony_ci{ 34bf215546Sopenharmony_ci return t.count() / 1000000.0f; 35bf215546Sopenharmony_ci} 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_civoid GpuDataSource::OnSetup(const SetupArgs &args) 38bf215546Sopenharmony_ci{ 39bf215546Sopenharmony_ci // Create drivers for all supported devices 40bf215546Sopenharmony_ci auto drm_devices = DrmDevice::create_all(); 41bf215546Sopenharmony_ci for (auto &drm_device : drm_devices) { 42bf215546Sopenharmony_ci if (drm_device.name != driver_name) 43bf215546Sopenharmony_ci continue; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci if (auto driver = Driver::get_driver(std::move(drm_device))) { 46bf215546Sopenharmony_ci if (!driver->init_perfcnt()) { 47bf215546Sopenharmony_ci // Skip failing driver 48bf215546Sopenharmony_ci PPS_LOG_ERROR("Failed to initialize %s driver", driver->drm_device.name.c_str()); 49bf215546Sopenharmony_ci continue; 50bf215546Sopenharmony_ci } 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci this->driver = driver; 53bf215546Sopenharmony_ci } 54bf215546Sopenharmony_ci } 55bf215546Sopenharmony_ci if (driver == nullptr) { 56bf215546Sopenharmony_ci PPS_LOG_FATAL("No DRM devices supported"); 57bf215546Sopenharmony_ci } 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci // Parse perfetto config 60bf215546Sopenharmony_ci const std::string &config_raw = args.config->gpu_counter_config_raw(); 61bf215546Sopenharmony_ci perfetto::protos::pbzero::GpuCounterConfig::Decoder config(config_raw); 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci if (config.has_counter_ids()) { 64bf215546Sopenharmony_ci // Get enabled counters 65bf215546Sopenharmony_ci PPS_LOG_IMPORTANT("Selecting counters"); 66bf215546Sopenharmony_ci for (auto it = config.counter_ids(); it; ++it) { 67bf215546Sopenharmony_ci uint32_t counter_id = it->as_uint32(); 68bf215546Sopenharmony_ci driver->enable_counter(counter_id); 69bf215546Sopenharmony_ci } 70bf215546Sopenharmony_ci } else { 71bf215546Sopenharmony_ci // Enable all counters 72bf215546Sopenharmony_ci driver->enable_all_counters(); 73bf215546Sopenharmony_ci } 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci // Get sampling period 76bf215546Sopenharmony_ci auto min_sampling_period = std::chrono::nanoseconds(MIN_SAMPLING_PERIOD_NS); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci auto dev_supported = std::chrono::nanoseconds(driver->get_min_sampling_period_ns()); 79bf215546Sopenharmony_ci if (dev_supported > min_sampling_period) { 80bf215546Sopenharmony_ci min_sampling_period = dev_supported; 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci time_to_sleep = std::max(time_to_sleep, min_sampling_period); 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci if (config.has_counter_period_ns()) { 86bf215546Sopenharmony_ci auto requested_sampling_period = std::chrono::nanoseconds(config.counter_period_ns()); 87bf215546Sopenharmony_ci if (requested_sampling_period < min_sampling_period) { 88bf215546Sopenharmony_ci PPS_LOG_ERROR("Sampling period should be greater than %" PRIu64 " ns (%.2f ms)", 89bf215546Sopenharmony_ci uint64_t(min_sampling_period.count()), 90bf215546Sopenharmony_ci ms(min_sampling_period)); 91bf215546Sopenharmony_ci } else { 92bf215546Sopenharmony_ci time_to_sleep = requested_sampling_period; 93bf215546Sopenharmony_ci } 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci PPS_LOG("Sampling period set to %" PRIu64 " ns", uint64_t(time_to_sleep.count())); 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_civoid GpuDataSource::OnStart(const StartArgs &args) 99bf215546Sopenharmony_ci{ 100bf215546Sopenharmony_ci driver->enable_perfcnt(time_to_sleep.count()); 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci state = State::Start; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci { 105bf215546Sopenharmony_ci std::lock_guard<std::mutex> lock(started_m); 106bf215546Sopenharmony_ci started = true; 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci started_cv.notify_all(); 109bf215546Sopenharmony_ci} 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_civoid close_callback(GpuDataSource::TraceContext ctx) 112bf215546Sopenharmony_ci{ 113bf215546Sopenharmony_ci auto packet = ctx.NewTracePacket(); 114bf215546Sopenharmony_ci packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME); 115bf215546Sopenharmony_ci packet->set_timestamp(perfetto::base::GetBootTimeNs().count()); 116bf215546Sopenharmony_ci packet->Finalize(); 117bf215546Sopenharmony_ci ctx.Flush(); 118bf215546Sopenharmony_ci PPS_LOG("Context flushed"); 119bf215546Sopenharmony_ci} 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_civoid GpuDataSource::OnStop(const StopArgs &args) 122bf215546Sopenharmony_ci{ 123bf215546Sopenharmony_ci state = State::Stop; 124bf215546Sopenharmony_ci auto stop_closure = args.HandleStopAsynchronously(); 125bf215546Sopenharmony_ci Trace(close_callback); 126bf215546Sopenharmony_ci stop_closure(); 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci driver->disable_perfcnt(); 129bf215546Sopenharmony_ci driver = nullptr; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci std::lock_guard<std::mutex> lock(started_m); 132bf215546Sopenharmony_ci started = false; 133bf215546Sopenharmony_ci} 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_civoid GpuDataSource::wait_started() 136bf215546Sopenharmony_ci{ 137bf215546Sopenharmony_ci std::unique_lock<std::mutex> lock(started_m); 138bf215546Sopenharmony_ci if (!started) { 139bf215546Sopenharmony_ci PPS_LOG("Waiting for start"); 140bf215546Sopenharmony_ci started_cv.wait(lock, [] { return started; }); 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci} 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_civoid GpuDataSource::register_data_source(const std::string &_driver_name) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci driver_name = _driver_name; 147bf215546Sopenharmony_ci static perfetto::DataSourceDescriptor dsd; 148bf215546Sopenharmony_ci dsd.set_name("gpu.counters." + driver_name); 149bf215546Sopenharmony_ci Register(dsd); 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_civoid add_group(perfetto::protos::pbzero::GpuCounterDescriptor *desc, 153bf215546Sopenharmony_ci const CounterGroup &group, 154bf215546Sopenharmony_ci const std::string &prefix, 155bf215546Sopenharmony_ci int32_t gpu_num) 156bf215546Sopenharmony_ci{ 157bf215546Sopenharmony_ci if (!group.counters.empty()) { 158bf215546Sopenharmony_ci // Define a block for each group containing counters 159bf215546Sopenharmony_ci auto block_desc = desc->add_blocks(); 160bf215546Sopenharmony_ci block_desc->set_name(prefix + "." + group.name); 161bf215546Sopenharmony_ci block_desc->set_block_id(group.id); 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci // Associate counters to blocks 164bf215546Sopenharmony_ci for (auto id : group.counters) { 165bf215546Sopenharmony_ci block_desc->add_counter_ids(id); 166bf215546Sopenharmony_ci } 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci for (auto const &sub : group.subgroups) { 170bf215546Sopenharmony_ci // Perfetto doesnt currently support nested groups. 171bf215546Sopenharmony_ci // Flatten group hierarchy, using dot separator 172bf215546Sopenharmony_ci add_group(desc, sub, prefix + "." + group.name, gpu_num); 173bf215546Sopenharmony_ci } 174bf215546Sopenharmony_ci} 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_civoid add_descriptors(perfetto::protos::pbzero::GpuCounterEvent *event, 177bf215546Sopenharmony_ci std::vector<CounterGroup> const &groups, 178bf215546Sopenharmony_ci std::vector<Counter> const &counters, 179bf215546Sopenharmony_ci Driver &driver) 180bf215546Sopenharmony_ci{ 181bf215546Sopenharmony_ci // Start a counter descriptor 182bf215546Sopenharmony_ci auto desc = event->set_counter_descriptor(); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci // Add the groups 185bf215546Sopenharmony_ci for (auto const &group : groups) { 186bf215546Sopenharmony_ci add_group(desc, group, driver.drm_device.name, driver.drm_device.gpu_num); 187bf215546Sopenharmony_ci } 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci // Add the counters 190bf215546Sopenharmony_ci for (auto const &counter : counters) { 191bf215546Sopenharmony_ci auto spec = desc->add_specs(); 192bf215546Sopenharmony_ci spec->set_counter_id(counter.id); 193bf215546Sopenharmony_ci spec->set_name(counter.name); 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci auto units = perfetto::protos::pbzero::GpuCounterDescriptor::NONE; 196bf215546Sopenharmony_ci switch (counter.units) { 197bf215546Sopenharmony_ci case Counter::Units::Percent: 198bf215546Sopenharmony_ci units = perfetto::protos::pbzero::GpuCounterDescriptor::PERCENT; 199bf215546Sopenharmony_ci break; 200bf215546Sopenharmony_ci case Counter::Units::Byte: 201bf215546Sopenharmony_ci units = perfetto::protos::pbzero::GpuCounterDescriptor::BYTE; 202bf215546Sopenharmony_ci break; 203bf215546Sopenharmony_ci case Counter::Units::Hertz: 204bf215546Sopenharmony_ci units = perfetto::protos::pbzero::GpuCounterDescriptor::HERTZ; 205bf215546Sopenharmony_ci break; 206bf215546Sopenharmony_ci case Counter::Units::None: 207bf215546Sopenharmony_ci units = perfetto::protos::pbzero::GpuCounterDescriptor::NONE; 208bf215546Sopenharmony_ci break; 209bf215546Sopenharmony_ci default: 210bf215546Sopenharmony_ci assert(false && "Missing counter units type!"); 211bf215546Sopenharmony_ci break; 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci spec->add_numerator_units(units); 214bf215546Sopenharmony_ci } 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_civoid add_samples(perfetto::protos::pbzero::GpuCounterEvent &event, const Driver &driver) 218bf215546Sopenharmony_ci{ 219bf215546Sopenharmony_ci if (driver.enabled_counters.size() == 0) { 220bf215546Sopenharmony_ci PPS_LOG_FATAL("There are no counters enabled"); 221bf215546Sopenharmony_ci } 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci for (const auto &counter : driver.enabled_counters) { 224bf215546Sopenharmony_ci auto counter_event = event.add_counters(); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci counter_event->set_counter_id(counter.id); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci auto value = counter.get_value(driver); 229bf215546Sopenharmony_ci if (auto d_value = std::get_if<double>(&value)) { 230bf215546Sopenharmony_ci counter_event->set_double_value(*d_value); 231bf215546Sopenharmony_ci } else if (auto i_value = std::get_if<int64_t>(&value)) { 232bf215546Sopenharmony_ci counter_event->set_int_value(*i_value); 233bf215546Sopenharmony_ci } else { 234bf215546Sopenharmony_ci PPS_LOG_ERROR("Failed to get value for counter %s", counter.name.c_str()); 235bf215546Sopenharmony_ci } 236bf215546Sopenharmony_ci } 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_civoid add_timestamp(perfetto::protos::pbzero::ClockSnapshot *event, const Driver *driver) 240bf215546Sopenharmony_ci{ 241bf215546Sopenharmony_ci uint32_t gpu_clock_id = driver->gpu_clock_id(); 242bf215546Sopenharmony_ci if (perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME == gpu_clock_id) 243bf215546Sopenharmony_ci return; 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci // Send a correlation event between GPU & CPU timestamps 246bf215546Sopenharmony_ci uint64_t cpu_ts = perfetto::base::GetBootTimeNs().count(); 247bf215546Sopenharmony_ci uint64_t gpu_ts = driver->gpu_timestamp(); 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci { 250bf215546Sopenharmony_ci auto clock = event->add_clocks(); 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci clock->set_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME); 253bf215546Sopenharmony_ci clock->set_timestamp(cpu_ts); 254bf215546Sopenharmony_ci } 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci { 257bf215546Sopenharmony_ci auto clock = event->add_clocks(); 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci clock->set_clock_id(gpu_clock_id); 260bf215546Sopenharmony_ci clock->set_timestamp(gpu_ts); 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci} 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_civoid GpuDataSource::trace(TraceContext &ctx) 265bf215546Sopenharmony_ci{ 266bf215546Sopenharmony_ci using namespace perfetto::protos::pbzero; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci if (auto state = ctx.GetIncrementalState(); state->was_cleared) { 269bf215546Sopenharmony_ci descriptor_timestamp = perfetto::base::GetBootTimeNs().count(); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci { 272bf215546Sopenharmony_ci // Mark any incremental state before this point invalid 273bf215546Sopenharmony_ci auto packet = ctx.NewTracePacket(); 274bf215546Sopenharmony_ci packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME); 275bf215546Sopenharmony_ci packet->set_timestamp(descriptor_timestamp); 276bf215546Sopenharmony_ci packet->set_sequence_flags(TracePacket::SEQ_INCREMENTAL_STATE_CLEARED); 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci descriptor_timestamp = perfetto::base::GetBootTimeNs().count(); 280bf215546Sopenharmony_ci { 281bf215546Sopenharmony_ci // Counter descriptions 282bf215546Sopenharmony_ci auto packet = ctx.NewTracePacket(); 283bf215546Sopenharmony_ci packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME); 284bf215546Sopenharmony_ci packet->set_timestamp(descriptor_timestamp); 285bf215546Sopenharmony_ci auto event = packet->set_gpu_counter_event(); 286bf215546Sopenharmony_ci event->set_gpu_id(driver->drm_device.gpu_num); 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci auto &groups = driver->groups; 289bf215546Sopenharmony_ci auto &counters = driver->enabled_counters; 290bf215546Sopenharmony_ci add_descriptors(event, groups, counters, *driver); 291bf215546Sopenharmony_ci } 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci { 294bf215546Sopenharmony_ci // Initial timestamp correlation event 295bf215546Sopenharmony_ci auto packet = ctx.NewTracePacket(); 296bf215546Sopenharmony_ci packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME); 297bf215546Sopenharmony_ci packet->set_timestamp(descriptor_timestamp); 298bf215546Sopenharmony_ci last_correlation_timestamp = perfetto::base::GetBootTimeNs().count(); 299bf215546Sopenharmony_ci auto event = packet->set_clock_snapshot(); 300bf215546Sopenharmony_ci add_timestamp(event, driver); 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci // Capture GPU timestamp of the first packet. Anything prior to this can 304bf215546Sopenharmony_ci // be discarded. 305bf215546Sopenharmony_ci descriptor_gpu_timestamp = driver->gpu_timestamp(); 306bf215546Sopenharmony_ci state->was_cleared = false; 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci // Save current scheduler for restoring later 310bf215546Sopenharmony_ci int prev_sched_policy = sched_getscheduler(0); 311bf215546Sopenharmony_ci sched_param prev_priority_param; 312bf215546Sopenharmony_ci sched_getparam(0, &prev_priority_param); 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci // Use FIFO policy to avoid preemption while collecting counters 315bf215546Sopenharmony_ci int sched_policy = SCHED_FIFO; 316bf215546Sopenharmony_ci // Do not use max priority to avoid starving migration and watchdog threads 317bf215546Sopenharmony_ci int priority_value = sched_get_priority_max(sched_policy) - 1; 318bf215546Sopenharmony_ci sched_param priority_param { priority_value }; 319bf215546Sopenharmony_ci sched_setscheduler(0, sched_policy, &priority_param); 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci if (driver->dump_perfcnt()) { 322bf215546Sopenharmony_ci while (auto gpu_timestamp = driver->next()) { 323bf215546Sopenharmony_ci if (gpu_timestamp <= descriptor_gpu_timestamp) { 324bf215546Sopenharmony_ci // Do not send counter values before counter descriptors 325bf215546Sopenharmony_ci PPS_LOG_ERROR("Skipping counter values coming before descriptors"); 326bf215546Sopenharmony_ci continue; 327bf215546Sopenharmony_ci } 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci auto packet = ctx.NewTracePacket(); 330bf215546Sopenharmony_ci packet->set_timestamp_clock_id(driver->gpu_clock_id()); 331bf215546Sopenharmony_ci packet->set_timestamp(gpu_timestamp); 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci auto event = packet->set_gpu_counter_event(); 334bf215546Sopenharmony_ci event->set_gpu_id(driver->drm_device.gpu_num); 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci add_samples(*event, *driver); 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci } 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci uint64_t cpu_ts = perfetto::base::GetBootTimeNs().count(); 341bf215546Sopenharmony_ci if ((cpu_ts - last_correlation_timestamp) > CORRELATION_TIMESTAMP_PERIOD) { 342bf215546Sopenharmony_ci auto packet = ctx.NewTracePacket(); 343bf215546Sopenharmony_ci packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME); 344bf215546Sopenharmony_ci packet->set_timestamp(cpu_ts); 345bf215546Sopenharmony_ci auto event = packet->set_clock_snapshot(); 346bf215546Sopenharmony_ci add_timestamp(event, driver); 347bf215546Sopenharmony_ci last_correlation_timestamp = cpu_ts; 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci // Reset normal scheduler 351bf215546Sopenharmony_ci sched_setscheduler(0, prev_sched_policy, &prev_priority_param); 352bf215546Sopenharmony_ci} 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_civoid GpuDataSource::trace_callback(TraceContext ctx) 355bf215546Sopenharmony_ci{ 356bf215546Sopenharmony_ci using namespace std::chrono; 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci nanoseconds sleep_time = nanoseconds(0); 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci if (auto data_source = ctx.GetDataSourceLocked()) { 361bf215546Sopenharmony_ci if (data_source->time_to_sleep > data_source->time_to_trace) { 362bf215546Sopenharmony_ci sleep_time = data_source->time_to_sleep - data_source->time_to_trace; 363bf215546Sopenharmony_ci } 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci // Wait sampling period before tracing 367bf215546Sopenharmony_ci std::this_thread::sleep_for(sleep_time); 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci auto time_zero = perfetto::base::GetBootTimeNs(); 370bf215546Sopenharmony_ci if (auto data_source = ctx.GetDataSourceLocked()) { 371bf215546Sopenharmony_ci // Check data source is still running 372bf215546Sopenharmony_ci if (data_source->state == pps::State::Start) { 373bf215546Sopenharmony_ci data_source->trace(ctx); 374bf215546Sopenharmony_ci data_source->time_to_trace = perfetto::base::GetBootTimeNs() - time_zero; 375bf215546Sopenharmony_ci } 376bf215546Sopenharmony_ci } else { 377bf215546Sopenharmony_ci PPS_LOG("Tracing finished"); 378bf215546Sopenharmony_ci } 379bf215546Sopenharmony_ci} 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci} // namespace pps 382