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