1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <ditto/cpu_work.h>
16
17 #include <ditto/logger.h>
18
19 namespace dittosuite {
20
CpuWork(const std::string & name,const Params & params)21 CpuWork::CpuWork(const std::string& name, const Params& params) : Instruction(name, params) {}
22
CpuWorkCycles(const Params & params,uint64_t cycles)23 CpuWorkCycles::CpuWorkCycles(const Params& params, uint64_t cycles)
24 : CpuWork(kName, params), cycles_(cycles) {}
25
RunSingle()26 void CpuWorkCycles::RunSingle() {
27 volatile int target = -1;
28
29 for (uint64_t counter = 0; counter < cycles_; ++counter) {
30 target = ~target;
31 }
32 }
33
CpuWorkUtilization(const Params & params,double utilization)34 CpuWorkUtilization::CpuWorkUtilization(const Params& params, double utilization)
35 : CpuWork(kName, params) {
36 if (utilization < 0 || utilization > 1) {
37 LOGF("Utilization value must be in the range [0,1]");
38 }
39 if (params.period_us_ <= 0) {
40 LOGF("The period of the instruction must be greater than 0");
41 }
42 work_time_ = MicrosToTimespec(period_us_ * utilization);
43 }
44
threadWaitAbsoluteTime(const timespec & work_time)45 inline void threadWaitAbsoluteTime(const timespec& work_time) {
46 timespec time_now, time_end;
47
48 if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time_now)) {
49 LOGF("Error getting current time");
50 }
51
52 time_end = time_now + work_time;
53
54 do {
55 if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time_now)) {
56 LOGF("Error getting current time");
57 }
58 } while (time_now < time_end);
59 }
60
RunSingle()61 void CpuWorkUtilization::RunSingle() {
62 threadWaitAbsoluteTime(work_time_);
63 }
64
CpuWorkDurationUs(const Params & params,uint64_t duration_us)65 CpuWorkDurationUs::CpuWorkDurationUs(const Params& params, uint64_t duration_us)
66 : CpuWork(kName, params) {
67 work_time_ = MicrosToTimespec(duration_us);
68 }
69
RunSingle()70 void CpuWorkDurationUs::RunSingle() {
71 threadWaitAbsoluteTime(work_time_);
72 }
73
74 } // namespace dittosuite
75