#include #include #include #include #include #include #include TEST(DISABLED_PerformanceTest, SetCpuPartition) { int error; // Test setting the the partition for the current task. error = dvrSetCpuPartition(0, "/application/background"); EXPECT_EQ(0, error); error = dvrSetCpuPartition(0, "/application/performance"); EXPECT_EQ(0, error); // Test setting the partition for one of our tasks. bool done = false; pid_t task_id = 0; std::mutex mutex; std::condition_variable done_condition, id_condition; std::thread thread([&] { std::unique_lock lock(mutex); task_id = gettid(); id_condition.notify_one(); done_condition.wait(lock, [&done] { return done; }); }); { std::unique_lock lock(mutex); id_condition.wait(lock, [&task_id] { return task_id != 0; }); } EXPECT_NE(0, task_id); error = dvrSetCpuPartition(task_id, "/application"); EXPECT_EQ(0, error); { std::lock_guard lock(mutex); done = true; done_condition.notify_one(); } thread.join(); // Test setting the partition for a task that isn't valid using // the task id of the thread that we just joined. Technically the // id could wrap around by the time we get here, but this is // extremely unlikely. error = dvrSetCpuPartition(task_id, "/application"); EXPECT_EQ(-EINVAL, error); // Test setting the partition for a task that doesn't belong to us. error = dvrSetCpuPartition(1, "/application"); EXPECT_EQ(-EINVAL, error); // Test setting the partition to one that doesn't exist. error = dvrSetCpuPartition(0, "/foobar"); EXPECT_EQ(-ENOENT, error); } TEST(PerformanceTest, SetSchedulerClass) { int error; // TODO(eieio): Test all supported scheduler classes and priority levels. error = dvrSetSchedulerClass(0, "background"); EXPECT_EQ(0, error); EXPECT_EQ(SCHED_BATCH, sched_getscheduler(0)); error = dvrSetSchedulerClass(0, "audio:low"); EXPECT_EQ(0, error); EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0)); error = dvrSetSchedulerClass(0, "normal"); EXPECT_EQ(0, error); EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0)); error = dvrSetSchedulerClass(0, "foobar"); EXPECT_EQ(-EINVAL, error); } TEST(PerformanceTest, SchedulerClassResetOnFork) { int error; error = dvrSetSchedulerClass(0, "graphics:high"); EXPECT_EQ(0, error); EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0)); int scheduler = -1; std::thread thread([&]() { scheduler = sched_getscheduler(0); }); thread.join(); EXPECT_EQ(SCHED_NORMAL, scheduler); // Return to SCHED_NORMAL. error = dvrSetSchedulerClass(0, "normal"); EXPECT_EQ(0, error); EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0)); } TEST(PerformanceTest, GetCpuPartition) { int error; char partition[PATH_MAX + 1]; error = dvrSetCpuPartition(0, "/"); ASSERT_EQ(0, error); error = dvrGetCpuPartition(0, partition, sizeof(partition)); EXPECT_EQ(0, error); EXPECT_EQ("/", std::string(partition)); error = dvrSetCpuPartition(0, "/application"); EXPECT_EQ(0, error); error = dvrGetCpuPartition(0, partition, sizeof(partition)); EXPECT_EQ(0, error); EXPECT_EQ("/application", std::string(partition)); // Test passing a buffer that is too short. error = dvrGetCpuPartition(0, partition, 5); EXPECT_EQ(-ENOBUFS, error); // Test getting the partition for a task that doesn't belong to us. error = dvrGetCpuPartition(1, partition, sizeof(partition)); EXPECT_EQ(-EINVAL, error); // Test passing a nullptr value for partition buffer. error = dvrGetCpuPartition(0, nullptr, sizeof(partition)); EXPECT_EQ(-EINVAL, error); }