diff options
author | Alessio Balsini <balsini@google.com> | 2023-10-13 22:31:19 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-10-13 22:31:19 +0000 |
commit | 0201cd0ce689d266beb14ea9569629f3d463abb0 (patch) | |
tree | 6e15dd93d9a58e8cdbca24e847ea69ae0b8ca9db | |
parent | 9be19e114fa97ef8d8066afc7901231b9cb58413 (diff) | |
parent | f6a34da4385c98cb1f5c131da6cc24cc6e8846db (diff) | |
download | dittosuite-0201cd0ce689d266beb14ea9569629f3d463abb0.tar.gz |
Implement scheduling attributes am: 93a7c4db13 am: 027af9914f am: 212ad1d715 am: 8ba8ab80a4 am: f6a34da438
Original change: https://android-review.googlesource.com/c/platform/test/dittosuite/+/2786221
Change-Id: I4d186bdad708049a7884af7625d73775a1a33fa9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | example/cpu_workload.ditto | 1 | ||||
-rw-r--r-- | example/sched_policies.ditto | 56 | ||||
-rw-r--r-- | include/ditto/multithreading_utils.h | 54 | ||||
-rw-r--r-- | schema/benchmark.proto | 36 | ||||
-rw-r--r-- | src/instruction.cpp | 4 | ||||
-rw-r--r-- | src/instruction_factory.cpp | 9 | ||||
-rw-r--r-- | src/multiprocessing.cpp | 4 | ||||
-rw-r--r-- | src/multithreading_utils.cpp | 99 |
8 files changed, 261 insertions, 2 deletions
diff --git a/example/cpu_workload.ditto b/example/cpu_workload.ditto index d55caa9..d86b871 100644 --- a/example/cpu_workload.ditto +++ b/example/cpu_workload.ditto @@ -1,5 +1,6 @@ main: { multithreading: { + fork: true; threads: [ { name: "Cycles" diff --git a/example/sched_policies.ditto b/example/sched_policies.ditto new file mode 100644 index 0000000..035f2c0 --- /dev/null +++ b/example/sched_policies.ditto @@ -0,0 +1,56 @@ +main: { + multithreading: { + fork: false; + threads: [ + { + name: "Deadline" + sched_attr: { + deadline: { + policy: DEADLINE, + runtime: 30000000, + deadline: 40000000, + period: 40000000, + } + } + instruction: { + cpu_work: { + utilization: 0.1 + } + repeat: 100, + period_us: 40000 + }, + }, + { + name: "RtHighPrio" + sched_attr: { + rt: { + policy: FIFO, priority: 99 + } + } + instruction: { + cpu_work: { + utilization: 0.2 + } + repeat: 100, + period_us: 60000 + }, + }, + { + name: "RtLowPrio" + sched_attr: { + rt: { + policy: FIFO, priority: 1 + } + } + instruction: { + cpu_work: { + utilization: 0.5 + } + repeat: 100, + period_us: 50000 + }, + } + ] + } +} +global: {} diff --git a/include/ditto/multithreading_utils.h b/include/ditto/multithreading_utils.h index 5c03a1b..b46272a 100644 --- a/include/ditto/multithreading_utils.h +++ b/include/ditto/multithreading_utils.h @@ -14,12 +14,64 @@ #pragma once +#ifdef __ANDROID__ +#include <benchmark.pb.h> +#else +#include "schema/benchmark.pb.h" +#endif + +#include <ditto/logger.h> + +#include <sys/syscall.h> +#include <unistd.h> + namespace dittosuite { +enum SchedPolicy { + SchedNormal = 0, + SchedFifo = 1, + SchedRr = 2, + SchedBatch = 3, + /* SchedIso: reserved but not implemented yet */ + SchedIdle = 5, + SchedDeadline = 6, +}; + +struct SchedAttr__ { + uint32_t size; /* Size of this structure */ + uint32_t sched_policy; /* Policy (SCHED_*) */ + uint64_t sched_flags; /* Flags */ + + int32_t sched_nice; /* Nice value (SCHED_OTHER, + SCHED_BATCH) */ + uint32_t sched_priority; /* Static priority (SCHED_FIFO, + SCHED_RR) */ + /* Remaining fields are for SCHED_DEADLINE */ + uint64_t sched_runtime; + uint64_t sched_deadline; + uint64_t sched_period; +}; + +std::string to_string(const SchedAttr__& attr); + +class SchedAttr { + bool initialized_ = false; + SchedAttr__ sched_attr_; + + public: + void Set() const; + bool IsSet() const; + + SchedAttr& operator=(const dittosuiteproto::SchedAttr& pb); +}; + + struct MultithreadingParams { const std::string name_; + SchedAttr sched_attr_; - MultithreadingParams(const std::string& name) : name_(name) {} + MultithreadingParams(const std::string& name, const SchedAttr& sched_attr) + : name_(name), sched_attr_(sched_attr) {} }; } // namespace dittosuite diff --git a/schema/benchmark.proto b/schema/benchmark.proto index fd2488c..5c5d182 100644 --- a/schema/benchmark.proto +++ b/schema/benchmark.proto @@ -113,6 +113,42 @@ message Thread { required Instruction instruction = 1; optional int32 spawn = 2 [default = 1]; optional string name = 3; + optional SchedAttr sched_attr = 4; +} + +message SchedAttr { + message SchedOther { + enum SchedPolicy { + OTHER = 1; + BATCH = 2; + } + required SchedPolicy policy = 1; + optional int32 nice = 2 [default = 10]; + } + message SchedRt { + enum SchedPolicy { + FIFO = 1; + RR = 2; + } + required SchedPolicy policy = 1; + required uint32 priority = 2; + } + message SchedDeadline { + enum SchedPolicy { + DEADLINE = 1; + } + required SchedPolicy policy = 1; + required uint64 runtime = 2; + required uint64 deadline = 3; + required uint64 period = 4; + } + + optional uint64 flags = 1 [default = 0]; + oneof attributes { + SchedOther other = 2; + SchedRt rt = 3; + SchedDeadline deadline = 4; + } } message Multithreading { diff --git a/src/instruction.cpp b/src/instruction.cpp index 07c4d1d..8195303 100644 --- a/src/instruction.cpp +++ b/src/instruction.cpp @@ -50,6 +50,10 @@ void Instruction::RunSynchronized(pthread_barrier_t* barrier, const Multithreadi } } + if (params.sched_attr_.IsSet()) { + params.sched_attr_.Set(); + } + pthread_barrier_wait(barrier); Instruction::Run(); } diff --git a/src/instruction_factory.cpp b/src/instruction_factory.cpp index 691b6a4..5833fb2 100644 --- a/src/instruction_factory.cpp +++ b/src/instruction_factory.cpp @@ -29,6 +29,7 @@ #include <ditto/logger.h> #include <ditto/multiprocessing.h> #include <ditto/multithreading.h> +#include <ditto/multithreading_utils.h> #include <ditto/open_file.h> #include <ditto/read_directory.h> #include <ditto/read_write_file.h> @@ -217,7 +218,13 @@ std::unique_ptr<Instruction> InstructionFactory::CreateFromProtoInstruction( } else { thread_name = std::to_string(i); } - thread_params.push_back(MultithreadingParams(thread_name)); + + SchedAttr sched_attr = {}; + if (thread.has_sched_attr()) { + sched_attr = thread.sched_attr(); + } + + thread_params.push_back(MultithreadingParams(thread_name, sched_attr)); } } diff --git a/src/multiprocessing.cpp b/src/multiprocessing.cpp index 43c6735..91f95be 100644 --- a/src/multiprocessing.cpp +++ b/src/multiprocessing.cpp @@ -101,6 +101,10 @@ void Multiprocessing::SetUpSingle() { PLOGF("Unable to set process name"); } + if (thread_params_[instruction_id_].sched_attr_.IsSet()) { + thread_params_[instruction_id_].sched_attr_.Set(); + } + LOGD("Process initializing instruction: " + std::to_string(instruction_id_) + " pid: " + std::to_string(getpid())); instructions_[instruction_id_]->SetUp(); diff --git a/src/multithreading_utils.cpp b/src/multithreading_utils.cpp new file mode 100644 index 0000000..493c009 --- /dev/null +++ b/src/multithreading_utils.cpp @@ -0,0 +1,99 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <ditto/multithreading_utils.h> + +namespace dittosuite { + +std::string to_string(const SchedAttr__& attr) { + std::string ret; + + ret += "size: " + std::to_string(attr.size); + ret += ", policy: " + std::to_string(attr.sched_policy); + ret += ", flags: " + std::to_string(attr.sched_flags); + ret += ", nice: " + std::to_string(attr.sched_nice); + ret += ", priority: " + std::to_string(attr.sched_priority); + ret += ", runtime: " + std::to_string(attr.sched_runtime); + ret += ", deadline: " + std::to_string(attr.sched_deadline); + ret += ", period: " + std::to_string(attr.sched_period); + + return ret; +} + +bool SchedAttr::IsSet() const { return initialized_; } + +void SchedAttr::Set() const { + if (!initialized_) { + LOGF("Setting uninitialized scheduling attributes"); + } + + LOGD("Setting scheduling policy [" + std::to_string(sched_attr_.sched_policy) + + "] to thread: " + std::to_string(gettid())); + + int ret = syscall(SYS_sched_setattr, 0 /* self */, &sched_attr_, 0 /* still not implemented */); + if (ret) { + PLOGF("Failed setting scheduling attributes \n" + to_string(sched_attr_) + "\n"); + } +} + +SchedAttr& SchedAttr::operator=(const dittosuiteproto::SchedAttr& pb) { + typedef dittosuiteproto::SchedAttr::AttributesCase SchedType; + + sched_attr_.size = sizeof(sched_attr_); + + sched_attr_.sched_flags = pb.flags(); + + switch (pb.attributes_case()) { + case SchedType::kOther: + switch (pb.other().policy()) { + case dittosuiteproto::SchedAttr::SchedOther::OTHER: + sched_attr_.sched_policy = SchedPolicy::SchedNormal; + break; + case dittosuiteproto::SchedAttr::SchedOther::BATCH: + sched_attr_.sched_policy = SchedPolicy::SchedBatch; + break; + } + sched_attr_.sched_nice = pb.other().nice(); + break; + case SchedType::kRt: + switch (pb.rt().policy()) { + case dittosuiteproto::SchedAttr::SchedRt::FIFO: + sched_attr_.sched_policy = SchedPolicy::SchedFifo; + break; + case dittosuiteproto::SchedAttr::SchedRt::RR: + sched_attr_.sched_policy = SchedPolicy::SchedRr; + break; + } + if (pb.rt().priority() < 1 || pb.rt().priority() > 99) { + LOGF("Scheduling priority should be in the range [1, 99]"); + } + sched_attr_.sched_priority = pb.rt().priority(); + break; + case SchedType::kDeadline: + sched_attr_.sched_policy = SchedPolicy::SchedDeadline; + sched_attr_.sched_runtime = pb.deadline().runtime(); + sched_attr_.sched_deadline = pb.deadline().deadline(); + sched_attr_.sched_period = pb.deadline().period(); + break; + case SchedType::ATTRIBUTES_NOT_SET: + LOGF("Missing scheduling attribute"); + break; + } + + initialized_ = true; + + return *this; +} + +} // namespace dittosuite |