1#include "benchmark_api_internal.h"
2
3#include <cinttypes>
4
5#include "string_util.h"
6
7namespace benchmark {
8namespace internal {
9
10BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
11 int per_family_instance_idx,
12 const std::vector<int64_t>& args,
13 int thread_count)
14 : benchmark_(*benchmark),
15 family_index_(family_idx),
16 per_family_instance_index_(per_family_instance_idx),
17 aggregation_report_mode_(benchmark_.aggregation_report_mode_),
18 args_(args),
19 time_unit_(benchmark_.time_unit_),
20 measure_process_cpu_time_(benchmark_.measure_process_cpu_time_),
21 use_real_time_(benchmark_.use_real_time_),
22 use_manual_time_(benchmark_.use_manual_time_),
23 complexity_(benchmark_.complexity_),
24 complexity_lambda_(benchmark_.complexity_lambda_),
25 statistics_(benchmark_.statistics_),
26 repetitions_(benchmark_.repetitions_),
27 min_time_(benchmark_.min_time_),
28 iterations_(benchmark_.iterations_),
29 threads_(thread_count) {
30 name_.function_name = benchmark_.name_;
31
32 size_t arg_i = 0;
33 for (const auto& arg : args) {
34 if (!name_.args.empty()) {
35 name_.args += '/';
36 }
37
38 if (arg_i < benchmark->arg_names_.size()) {
39 const auto& arg_name = benchmark_.arg_names_[arg_i];
40 if (!arg_name.empty()) {
41 name_.args += StrFormat("%s:", arg_name.c_str());
42 }
43 }
44
45 name_.args += StrFormat("%" PRId64, arg);
46 ++arg_i;
47 }
48
49 if (!IsZero(benchmark->min_time_)) {
50 name_.min_time = StrFormat("min_time:%0.3f", benchmark_.min_time_);
51 }
52
53 if (benchmark_.iterations_ != 0) {
54 name_.iterations = StrFormat(
55 "iterations:%lu", static_cast<unsigned long>(benchmark_.iterations_));
56 }
57
58 if (benchmark_.repetitions_ != 0) {
59 name_.repetitions = StrFormat("repeats:%d", benchmark_.repetitions_);
60 }
61
62 if (benchmark_.measure_process_cpu_time_) {
63 name_.time_type = "process_time";
64 }
65
66 if (benchmark_.use_manual_time_) {
67 if (!name_.time_type.empty()) {
68 name_.time_type += '/';
69 }
70 name_.time_type += "manual_time";
71 } else if (benchmark_.use_real_time_) {
72 if (!name_.time_type.empty()) {
73 name_.time_type += '/';
74 }
75 name_.time_type += "real_time";
76 }
77
78 if (!benchmark_.thread_counts_.empty()) {
79 name_.threads = StrFormat("threads:%d", threads_);
80 }
81
82 setup_ = benchmark_.setup_;
83 teardown_ = benchmark_.teardown_;
84}
85
86State BenchmarkInstance::Run(
87 IterationCount iters, int thread_id, internal::ThreadTimer* timer,
88 internal::ThreadManager* manager,
89 internal::PerfCountersMeasurement* perf_counters_measurement) const {
90 State st(iters, args_, thread_id, threads_, timer, manager,
91 perf_counters_measurement);
92 benchmark_.Run(st);
93 return st;
94}
95
96void BenchmarkInstance::Setup() const {
97 if (setup_) {
98 State st(/*iters*/ 1, args_, /*thread_id*/ 0, threads_, nullptr, nullptr,
99 nullptr);
100 setup_(st);
101 }
102}
103
104void BenchmarkInstance::Teardown() const {
105 if (teardown_) {
106 State st(/*iters*/ 1, args_, /*thread_id*/ 0, threads_, nullptr, nullptr,
107 nullptr);
108 teardown_(st);
109 }
110}
111} // namespace internal
112} // namespace benchmark
113