xref: /aosp_15_r20/test/dittosuite/src/instruction.cpp (revision 6fa2df46f119dce7527f5beb2814eca0e6f886ac)
1*6fa2df46SAndroid Build Coastguard Worker // Copyright (C) 2021 The Android Open Source Project
2*6fa2df46SAndroid Build Coastguard Worker //
3*6fa2df46SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*6fa2df46SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*6fa2df46SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*6fa2df46SAndroid Build Coastguard Worker //
7*6fa2df46SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
8*6fa2df46SAndroid Build Coastguard Worker //
9*6fa2df46SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*6fa2df46SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*6fa2df46SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6fa2df46SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*6fa2df46SAndroid Build Coastguard Worker // limitations under the License.
14*6fa2df46SAndroid Build Coastguard Worker 
15*6fa2df46SAndroid Build Coastguard Worker #include <ditto/instruction.h>
16*6fa2df46SAndroid Build Coastguard Worker 
17*6fa2df46SAndroid Build Coastguard Worker #include <ditto/logger.h>
18*6fa2df46SAndroid Build Coastguard Worker #include <ditto/shared_variables.h>
19*6fa2df46SAndroid Build Coastguard Worker #include <ditto/timespec_utils.h>
20*6fa2df46SAndroid Build Coastguard Worker #include <ditto/tracer.h>
21*6fa2df46SAndroid Build Coastguard Worker 
22*6fa2df46SAndroid Build Coastguard Worker namespace dittosuite {
23*6fa2df46SAndroid Build Coastguard Worker 
Instruction(const std::string & name,const Params & params)24*6fa2df46SAndroid Build Coastguard Worker Instruction::Instruction(const std::string& name, const Params& params)
25*6fa2df46SAndroid Build Coastguard Worker     : name_(name),
26*6fa2df46SAndroid Build Coastguard Worker       syscall_(params.syscall_),
27*6fa2df46SAndroid Build Coastguard Worker       repeat_(params.repeat_),
28*6fa2df46SAndroid Build Coastguard Worker       period_us_(params.period_us_),
29*6fa2df46SAndroid Build Coastguard Worker       offset_us_(params.offset_us_),
30*6fa2df46SAndroid Build Coastguard Worker       next_wakeup_() {}
31*6fa2df46SAndroid Build Coastguard Worker 
SetUp()32*6fa2df46SAndroid Build Coastguard Worker void Instruction::SetUp() {
33*6fa2df46SAndroid Build Coastguard Worker   if (period_us_ || offset_us_) {
34*6fa2df46SAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &next_wakeup_);
35*6fa2df46SAndroid Build Coastguard Worker     LOGD("Instruction::SetUp, next wakeup at: " + TimespecToString(next_wakeup_));
36*6fa2df46SAndroid Build Coastguard Worker     if (offset_us_) {
37*6fa2df46SAndroid Build Coastguard Worker       next_wakeup_ = next_wakeup_ + MicrosToTimespec(offset_us_);
38*6fa2df46SAndroid Build Coastguard Worker     }
39*6fa2df46SAndroid Build Coastguard Worker   }
40*6fa2df46SAndroid Build Coastguard Worker }
41*6fa2df46SAndroid Build Coastguard Worker 
Run()42*6fa2df46SAndroid Build Coastguard Worker void Instruction::Run() {
43*6fa2df46SAndroid Build Coastguard Worker   for (int i = 0; i < repeat_; i++) {
44*6fa2df46SAndroid Build Coastguard Worker     SetUpSingle();
45*6fa2df46SAndroid Build Coastguard Worker     RunSingle();
46*6fa2df46SAndroid Build Coastguard Worker     TearDownSingle(i == repeat_ - 1);
47*6fa2df46SAndroid Build Coastguard Worker   }
48*6fa2df46SAndroid Build Coastguard Worker }
49*6fa2df46SAndroid Build Coastguard Worker 
RunSynchronized(pthread_barrier_t * barrier,const MultithreadingParams & params)50*6fa2df46SAndroid Build Coastguard Worker void Instruction::RunSynchronized(pthread_barrier_t* barrier, const MultithreadingParams& params) {
51*6fa2df46SAndroid Build Coastguard Worker   int ret = pthread_setname_np(pthread_self(), params.name_.c_str());
52*6fa2df46SAndroid Build Coastguard Worker   if (ret) {
53*6fa2df46SAndroid Build Coastguard Worker     if (ret == ERANGE) {
54*6fa2df46SAndroid Build Coastguard Worker       LOGF("Name too long for thread, max 15 chars allowed: " + params.name_);
55*6fa2df46SAndroid Build Coastguard Worker     } else {
56*6fa2df46SAndroid Build Coastguard Worker       LOGF("Error setting thread name: " + std::to_string(ret));
57*6fa2df46SAndroid Build Coastguard Worker     }
58*6fa2df46SAndroid Build Coastguard Worker   }
59*6fa2df46SAndroid Build Coastguard Worker 
60*6fa2df46SAndroid Build Coastguard Worker   if (params.sched_attr_.IsSet()) {
61*6fa2df46SAndroid Build Coastguard Worker     params.sched_attr_.Set();
62*6fa2df46SAndroid Build Coastguard Worker   }
63*6fa2df46SAndroid Build Coastguard Worker   if (params.sched_affinity_.IsSet()) {
64*6fa2df46SAndroid Build Coastguard Worker     params.sched_affinity_.Set();
65*6fa2df46SAndroid Build Coastguard Worker   }
66*6fa2df46SAndroid Build Coastguard Worker 
67*6fa2df46SAndroid Build Coastguard Worker   pthread_barrier_wait(barrier);
68*6fa2df46SAndroid Build Coastguard Worker   Instruction::Run();
69*6fa2df46SAndroid Build Coastguard Worker }
70*6fa2df46SAndroid Build Coastguard Worker 
SpawnThread(pthread_barrier_t * barrier,const MultithreadingParams & params)71*6fa2df46SAndroid Build Coastguard Worker std::thread Instruction::SpawnThread(pthread_barrier_t* barrier,
72*6fa2df46SAndroid Build Coastguard Worker                                      const MultithreadingParams& params) {
73*6fa2df46SAndroid Build Coastguard Worker   return std::thread([=, this] { RunSynchronized(barrier, params); });
74*6fa2df46SAndroid Build Coastguard Worker }
75*6fa2df46SAndroid Build Coastguard Worker 
TearDown()76*6fa2df46SAndroid Build Coastguard Worker void Instruction::TearDown() {}
77*6fa2df46SAndroid Build Coastguard Worker 
SetUpSingle()78*6fa2df46SAndroid Build Coastguard Worker void Instruction::SetUpSingle() {
79*6fa2df46SAndroid Build Coastguard Worker   if (period_us_ || offset_us_) {
80*6fa2df46SAndroid Build Coastguard Worker     if (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_wakeup_, nullptr)) {
81*6fa2df46SAndroid Build Coastguard Worker       PLOGF("Offset clock interrupted");
82*6fa2df46SAndroid Build Coastguard Worker     }
83*6fa2df46SAndroid Build Coastguard Worker     next_wakeup_ = next_wakeup_ + MicrosToTimespec(period_us_);
84*6fa2df46SAndroid Build Coastguard Worker   }
85*6fa2df46SAndroid Build Coastguard Worker   tracer_.Start(name_);
86*6fa2df46SAndroid Build Coastguard Worker   time_sampler_.MeasureStart();
87*6fa2df46SAndroid Build Coastguard Worker }
88*6fa2df46SAndroid Build Coastguard Worker 
TearDownSingle(bool)89*6fa2df46SAndroid Build Coastguard Worker void Instruction::TearDownSingle(bool /*is_last*/) {
90*6fa2df46SAndroid Build Coastguard Worker   time_sampler_.MeasureEnd();
91*6fa2df46SAndroid Build Coastguard Worker   tracer_.End(name_);
92*6fa2df46SAndroid Build Coastguard Worker }
93*6fa2df46SAndroid Build Coastguard Worker 
CollectResults(const std::string & prefix)94*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<Result> Instruction::CollectResults(const std::string& prefix) {
95*6fa2df46SAndroid Build Coastguard Worker   auto result = std::make_unique<Result>(prefix + name_, repeat_);
96*6fa2df46SAndroid Build Coastguard Worker   result->AddMeasurement("duration", TimespecToDoubleNanos(time_sampler_.GetSamples()));
97*6fa2df46SAndroid Build Coastguard Worker   return result;
98*6fa2df46SAndroid Build Coastguard Worker }
99*6fa2df46SAndroid Build Coastguard Worker 
SetAbsolutePathKey(int absolute_path_key)100*6fa2df46SAndroid Build Coastguard Worker void Instruction::SetAbsolutePathKey(int absolute_path_key) {
101*6fa2df46SAndroid Build Coastguard Worker   absolute_path_key_ = absolute_path_key;
102*6fa2df46SAndroid Build Coastguard Worker }
103*6fa2df46SAndroid Build Coastguard Worker 
SetArgv(char ** argv)104*6fa2df46SAndroid Build Coastguard Worker void Instruction::SetArgv(char** argv) {
105*6fa2df46SAndroid Build Coastguard Worker   argv_ = argv;
106*6fa2df46SAndroid Build Coastguard Worker }
107*6fa2df46SAndroid Build Coastguard Worker 
SetArgc(int argc)108*6fa2df46SAndroid Build Coastguard Worker void Instruction::SetArgc(int argc) {
109*6fa2df46SAndroid Build Coastguard Worker   argc_ = argc;
110*6fa2df46SAndroid Build Coastguard Worker }
111*6fa2df46SAndroid Build Coastguard Worker 
GetAbsolutePath()112*6fa2df46SAndroid Build Coastguard Worker std::string Instruction::GetAbsolutePath() {
113*6fa2df46SAndroid Build Coastguard Worker   return std::get<std::string>(SharedVariables::Get(absolute_path_key_));
114*6fa2df46SAndroid Build Coastguard Worker }
115*6fa2df46SAndroid Build Coastguard Worker 
116*6fa2df46SAndroid Build Coastguard Worker int Instruction::absolute_path_key_;
117*6fa2df46SAndroid Build Coastguard Worker char** Instruction::argv_;
118*6fa2df46SAndroid Build Coastguard Worker int Instruction::argc_;
119*6fa2df46SAndroid Build Coastguard Worker 
120*6fa2df46SAndroid Build Coastguard Worker }  // namespace dittosuite
121