android_system_core/libcutils/sched_policy_test.cpp
T.J. Mercier 981664df08 libprocessgroup: Remove schedtune support
Schedtune was an out of tree cgroup controller present in Android
kernels up to 4.19. It was replaced with uclamp and the cpu controller.
Now that 4.19 is EOL and unsupported, and schedtune is not present in
any supported Android kernels, remove the userspace support for
schedtune.

Bug: 362504801
Change-Id: If8baaf1a616984c5dbaac1bbd03e23ad001bc29c
2024-10-02 14:47:45 +00:00

119 lines
4 KiB
C++

/*
* Copyright (C) 2016 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 <algorithm>
#include <chrono>
#include <thread>
#include <vector>
#include <sys/capability.h>
#include <cutils/sched_policy.h>
#include <gtest/gtest.h>
bool hasCapSysNice() {
__user_cap_header_struct header;
memset(&header, 0, sizeof(header));
header.version = _LINUX_CAPABILITY_VERSION_3;
__user_cap_data_struct caps[_LINUX_CAPABILITY_U32S_3];
if (capget(&header, &caps[0])) {
GTEST_LOG_(WARNING) << "failed to get process capabilities";
return false;
}
auto nice_idx = CAP_TO_INDEX(CAP_SYS_NICE);
auto nice_mask = CAP_TO_MASK(CAP_SYS_NICE);
return caps[nice_idx].effective & nice_mask;
}
long long medianSleepTime() {
std::vector<long long> sleepTimes;
constexpr size_t numSamples = 100;
for (size_t i = 0; i < numSamples; i++) {
auto start = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::nanoseconds(1));
auto end = std::chrono::steady_clock::now();
auto diff = end - start;
sleepTimes.push_back(diff.count());
}
constexpr auto median = numSamples / 2;
std::nth_element(sleepTimes.begin(), sleepTimes.begin() + median,
sleepTimes.end());
return sleepTimes[median];
}
static void AssertPolicy(SchedPolicy expected_policy) {
SchedPolicy current_policy;
ASSERT_EQ(0, get_sched_policy(0, &current_policy));
EXPECT_EQ(expected_policy, current_policy);
}
TEST(SchedPolicy, set_sched_policy) {
ASSERT_EQ(0, set_sched_policy(0, SP_BACKGROUND));
ASSERT_EQ(0, set_cpuset_policy(0, SP_BACKGROUND));
AssertPolicy(SP_BACKGROUND);
ASSERT_EQ(0, set_sched_policy(0, SP_FOREGROUND));
ASSERT_EQ(0, set_cpuset_policy(0, SP_FOREGROUND));
AssertPolicy(SP_FOREGROUND);
}
TEST(SchedPolicy, set_sched_policy_timerslack) {
if (!hasCapSysNice()) {
GTEST_LOG_(INFO) << "skipping test that requires CAP_SYS_NICE";
return;
}
// A measureable effect of scheduling policy is that the kernel has 800x
// greater slack time in waking up a sleeping background thread.
//
// Look for 10x difference in how long FB and BG threads actually sleep
// when trying to sleep for 1 ns. This difference is large enough not
// to happen by chance, but small enough (compared to 800x) to keep inherent
// fuzziness in scheduler behavior from causing false negatives.
const unsigned int BG_FG_SLACK_FACTOR = 10;
ASSERT_EQ(0, set_sched_policy(0, SP_BACKGROUND));
auto bgSleepTime = medianSleepTime();
ASSERT_EQ(0, set_sched_policy(0, SP_FOREGROUND));
auto fgSleepTime = medianSleepTime();
ASSERT_GT(bgSleepTime, fgSleepTime * BG_FG_SLACK_FACTOR);
}
TEST(SchedPolicy, get_sched_policy_name) {
EXPECT_STREQ("bg", get_sched_policy_name(SP_BACKGROUND));
EXPECT_EQ(nullptr, get_sched_policy_name(SchedPolicy(-2)));
EXPECT_EQ(nullptr, get_sched_policy_name(SP_CNT));
}
TEST(SchedPolicy, get_cpuset_policy_profile_name) {
EXPECT_STREQ("CPUSET_SP_BACKGROUND", get_cpuset_policy_profile_name(SP_BACKGROUND));
EXPECT_EQ(nullptr, get_cpuset_policy_profile_name(SchedPolicy(-2)));
EXPECT_EQ(nullptr, get_cpuset_policy_profile_name(SP_CNT));
}
TEST(SchedPolicy, get_sched_policy_profile_name) {
EXPECT_STREQ("SCHED_SP_BACKGROUND", get_sched_policy_profile_name(SP_BACKGROUND));
EXPECT_EQ(nullptr, get_sched_policy_profile_name(SchedPolicy(-2)));
EXPECT_EQ(nullptr, get_sched_policy_profile_name(SP_CNT));
}