1#include <errno.h> 2#include <sched.h> 3 4#include <condition_variable> 5#include <mutex> 6#include <thread> 7 8#include <dvr/performance_client_api.h> 9#include <gtest/gtest.h> 10 11TEST(DISABLED_PerformanceTest, SetCpuPartition) { 12 int error; 13 14 // Test setting the the partition for the current task. 15 error = dvrSetCpuPartition(0, "/application/background"); 16 EXPECT_EQ(0, error); 17 18 error = dvrSetCpuPartition(0, "/application/performance"); 19 EXPECT_EQ(0, error); 20 21 // Test setting the partition for one of our tasks. 22 bool done = false; 23 pid_t task_id = 0; 24 std::mutex mutex; 25 std::condition_variable done_condition, id_condition; 26 27 std::thread thread([&] { 28 std::unique_lock<std::mutex> lock(mutex); 29 30 task_id = gettid(); 31 id_condition.notify_one(); 32 33 done_condition.wait(lock, [&done] { return done; }); 34 }); 35 36 { 37 std::unique_lock<std::mutex> lock(mutex); 38 id_condition.wait(lock, [&task_id] { return task_id != 0; }); 39 } 40 EXPECT_NE(0, task_id); 41 42 error = dvrSetCpuPartition(task_id, "/application"); 43 EXPECT_EQ(0, error); 44 45 { 46 std::lock_guard<std::mutex> lock(mutex); 47 done = true; 48 done_condition.notify_one(); 49 } 50 thread.join(); 51 52 // Test setting the partition for a task that isn't valid using 53 // the task id of the thread that we just joined. Technically the 54 // id could wrap around by the time we get here, but this is 55 // extremely unlikely. 56 error = dvrSetCpuPartition(task_id, "/application"); 57 EXPECT_EQ(-EINVAL, error); 58 59 // Test setting the partition for a task that doesn't belong to us. 60 error = dvrSetCpuPartition(1, "/application"); 61 EXPECT_EQ(-EINVAL, error); 62 63 // Test setting the partition to one that doesn't exist. 64 error = dvrSetCpuPartition(0, "/foobar"); 65 EXPECT_EQ(-ENOENT, error); 66} 67 68TEST(PerformanceTest, SetSchedulerClass) { 69 int error; 70 71 // TODO(eieio): Test all supported scheduler classes and priority levels. 72 73 error = dvrSetSchedulerClass(0, "background"); 74 EXPECT_EQ(0, error); 75 EXPECT_EQ(SCHED_BATCH, sched_getscheduler(0)); 76 77 error = dvrSetSchedulerClass(0, "audio:low"); 78 EXPECT_EQ(0, error); 79 EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0)); 80 81 error = dvrSetSchedulerClass(0, "normal"); 82 EXPECT_EQ(0, error); 83 EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0)); 84 85 error = dvrSetSchedulerClass(0, "foobar"); 86 EXPECT_EQ(-EINVAL, error); 87} 88 89TEST(PerformanceTest, SchedulerClassResetOnFork) { 90 int error; 91 92 error = dvrSetSchedulerClass(0, "graphics:high"); 93 EXPECT_EQ(0, error); 94 EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0)); 95 96 int scheduler = -1; 97 std::thread thread([&]() { scheduler = sched_getscheduler(0); }); 98 thread.join(); 99 100 EXPECT_EQ(SCHED_NORMAL, scheduler); 101 102 // Return to SCHED_NORMAL. 103 error = dvrSetSchedulerClass(0, "normal"); 104 EXPECT_EQ(0, error); 105 EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0)); 106} 107 108TEST(PerformanceTest, GetCpuPartition) { 109 int error; 110 char partition[PATH_MAX + 1]; 111 112 error = dvrSetCpuPartition(0, "/"); 113 ASSERT_EQ(0, error); 114 115 error = dvrGetCpuPartition(0, partition, sizeof(partition)); 116 EXPECT_EQ(0, error); 117 EXPECT_EQ("/", std::string(partition)); 118 119 error = dvrSetCpuPartition(0, "/application"); 120 EXPECT_EQ(0, error); 121 122 error = dvrGetCpuPartition(0, partition, sizeof(partition)); 123 EXPECT_EQ(0, error); 124 EXPECT_EQ("/application", std::string(partition)); 125 126 // Test passing a buffer that is too short. 127 error = dvrGetCpuPartition(0, partition, 5); 128 EXPECT_EQ(-ENOBUFS, error); 129 130 // Test getting the partition for a task that doesn't belong to us. 131 error = dvrGetCpuPartition(1, partition, sizeof(partition)); 132 EXPECT_EQ(-EINVAL, error); 133 134 // Test passing a nullptr value for partition buffer. 135 error = dvrGetCpuPartition(0, nullptr, sizeof(partition)); 136 EXPECT_EQ(-EINVAL, error); 137} 138