// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "sommelier-timing.h" // NOLINT(build/include_directory) #include #include #include #include #include #define NSEC_PER_SEC 1000000000 #define NSEC_PER_USEC 1000 static inline int64_t timespec_to_ns(timespec* t) { return (int64_t)t->tv_sec * NSEC_PER_SEC + t->tv_nsec; } // Records start time to calculate first delta. void Timing::RecordStartTime() { clock_gettime(CLOCK_REALTIME, &last_event); } int64_t Timing::GetTime() { timespec tp; clock_gettime(CLOCK_REALTIME, &tp); int64_t now = timespec_to_ns(&tp); int64_t last = timespec_to_ns(&last_event); last_event = tp; return now - last; } // Create a new action, add info gained from attach call. void Timing::UpdateLastAttach(int surface_id, int buffer_id) { actions[event_id % kMaxNumActions] = BufferAction(GetTime(), surface_id, buffer_id, BufferAction::ATTACH); event_id++; } // Create a new action, add info gained from commit call. void Timing::UpdateLastCommit(int surface_id) { actions[event_id % kMaxNumActions] = BufferAction( GetTime(), surface_id, kUnknownBufferId, BufferAction::COMMIT); event_id++; } // Add a release action with release timing info. void Timing::UpdateLastRelease(int buffer_id) { actions[event_id % kMaxNumActions] = BufferAction( GetTime(), kUnknownSurfaceId, buffer_id, BufferAction::RELEASE); event_id++; } // Output the recorded actions to the timing log file. void Timing::OutputLog() { if (event_id == 0) { std::cout << "No events in buffer, exiting" << std::endl; return; } std::cout << "Writing buffer activity to the timing log file" << std::endl; std::string output_filename = std::string(filename) + "_set_" + std::to_string(saves); std::ofstream outfile(output_filename); int start = 0; int buf_size = event_id; if (event_id >= kMaxNumActions) { start = event_id % kMaxNumActions; buf_size = kMaxNumActions; } outfile << "Type Surface_ID Buffer_ID Delta_Time" << std::endl; for (int i = 0; i < buf_size; i++) { int idx = (i + start) % kMaxNumActions; std::string type("?"); if (actions[idx].action_type == BufferAction::ATTACH) { type = "a"; } else if (actions[idx].action_type == BufferAction::COMMIT) { type = "c"; } else if (actions[idx].action_type == BufferAction::RELEASE) { type = "r"; } outfile << type << " "; outfile << actions[idx].surface_id << " "; outfile << actions[idx].buffer_id << " "; outfile << static_cast(actions[idx].delta_time) / NSEC_PER_USEC << std::endl; } std::stringstream nsec; nsec << std::setw(9) << std::setfill('0') << last_event.tv_nsec; outfile << "EndTime " << event_id - 1 << " " << last_event.tv_sec << "." << nsec.str() << std::endl; outfile.close(); std::cout << "Finished writing " << output_filename << std::endl; ++saves; }