| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/developer/debug/zxdb/common/perf_test.h" |
| |
| #include <lib/syslog/cpp/macros.h> |
| #include <lib/zx/clock.h> |
| #include <stdio.h> |
| |
| namespace zxdb { |
| |
| namespace { |
| |
| FILE* perf_log_file = nullptr; |
| bool written_perf_line = false; |
| |
| } // namespace |
| |
| bool InitPerfLog(const std::string& log_file) { |
| if (perf_log_file) { |
| // Trying to initialize twice. |
| FX_NOTREACHED(); |
| return false; |
| } |
| |
| if (!(perf_log_file = fopen(log_file.c_str(), "w"))) |
| return false; |
| |
| fprintf(perf_log_file, "{\n"); |
| return true; |
| } |
| |
| void FinalizePerfLog() { |
| if (!perf_log_file) { |
| // Trying to cleanup without initializing. |
| FX_NOTREACHED(); |
| return; |
| } |
| fprintf(perf_log_file, "\n}\n"); |
| fclose(perf_log_file); |
| perf_log_file = nullptr; |
| } |
| |
| void LogPerfResult(const char* test_suite_name, const char* test_name, double value, |
| const char* units) { |
| if (!perf_log_file) { |
| FX_NOTREACHED(); |
| return; |
| } |
| |
| // Format: //zircon/system/ulib/perftest/performance-results-schema.json |
| // Example line: |
| // {"label":"Vmo/CloneWrite/10000kbytes.close", |
| // "test_suite":"fuchsia.microbenchmarks", |
| // "unit":"nanoseconds", |
| // "values":[2346.961749]} |
| |
| // Add trailing comma for previous item when necessary. |
| if (written_perf_line) |
| fprintf(perf_log_file, ",\n"); |
| written_perf_line = true; |
| |
| fprintf(perf_log_file, R"({"label":"%s", "test_suite":"%s", "unit":"%s", "values":[%g]})", |
| test_name, test_suite_name, units, value); |
| fflush(stdout); |
| } |
| |
| PerfTimeLogger::PerfTimeLogger(const char* test_suite_name, const char* test_name) |
| : test_suite_name_(test_suite_name), test_name_(test_name) { |
| start_ = zx::clock::get_monotonic(); |
| } |
| |
| PerfTimeLogger::~PerfTimeLogger() { |
| if (!logged_) |
| Done(); |
| } |
| |
| void PerfTimeLogger::Done() { |
| // Use a floating-point millisecond value because it is more |
| // intuitive than microseconds and we want more precision than |
| // integer milliseconds |
| const double msecs = |
| (zx::clock::get_monotonic() - start_).to_nsecs() / |
| 1000000.0 LogPerfResult(test_suite_name_.c_str(), test_name_.c_str(), msecs, "ms"); |
| logged_ = true; |
| } |
| |
| } // namespace zxdb |