1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 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 16 #include <list> 17 #include <vector> 18 #include <queue> 19 #include <thread> 20 #include <gtest/gtest.h> 21 #define private public 22 #define protect public 23 #include "ffrt_inner.h" 24 25 #include "core/entity.h" 26 #include "sched/task_scheduler.h" 27 #include "sched/task_manager.h" 28 #include "core/task_attr_private.h" 29 #include "tm/scpu_task.h" 30 #include "sched/scheduler.h" 31 #include "../common.h" 32 33 using namespace std; 34 using namespace testing; 35 #ifdef HWTEST_TESTING_EXT_ENABLE 36 using namespace testing::ext; 37 #endif 38 using namespace ffrt; 39 40 class SchedulerTest : public testing::Test { 41 protected: SetUpTestCase()42 static void SetUpTestCase() 43 { 44 } 45 TearDownTestCase()46 static void TearDownTestCase() 47 { 48 } 49 SetUp()50 void SetUp() override 51 { 52 } 53 TearDown()54 void TearDown() override 55 { 56 } 57 }; 58 59 HWTEST_F(SchedulerTest, taskstate_test, TestSize.Level1) 60 { 61 std::queue<std::unique_ptr<SCPUEUTask>> tasks; 62 63 std::vector<TaskState::State> produceStatus; 64 std::vector<TaskState::State> consumeStatus; 65 66 #if (TASKSTAT_LOG_ENABLE == 1) 67 std::array<uint64_t, static_cast<size_t>(TaskState::MAX)> expectCount; 68 69 // record previous test units count 70 for (auto state = TaskState::PENDING; state != TaskState::MAX; ++(size_t&)state) { 71 expectCount[static_cast<size_t>(state)] = TaskManager::Instance().GetCount(state); 72 } 73 74 // expect non-exited state count equal zero 75 EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::PENDING)], 0); 76 EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::READY)], 0); 77 EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::RUNNING)], 0); 78 EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::BLOCKED)], 0); 79 __anon1b4591be0102(TaskState::State state) 80 auto increCount = [&expectCount](TaskState::State state) { ++expectCount[static_cast<size_t>(state)]; }; 81 __anon1b4591be0202(TaskState::State state) 82 auto decreCount = [&expectCount](TaskState::State state) { 83 if (expectCount[static_cast<size_t>(state)] > 0) { 84 --expectCount[static_cast<size_t>(state)]; 85 } 86 }; 87 #endif __anon1b4591be0302(CPUEUTask* task) 88 auto setState = [&](CPUEUTask* task) { 89 consumeStatus.emplace_back(task->state()); 90 return true; 91 }; 92 __anon1b4591be0402(TaskState::State state) 93 auto getNextState = [](TaskState::State state) { 94 switch (state) { 95 case TaskState::PENDING: 96 return TaskState::READY; 97 case TaskState::READY: 98 return TaskState::RUNNING; 99 case TaskState::RUNNING: 100 return TaskState::BLOCKED; 101 case TaskState::BLOCKED: 102 return TaskState::EXITED; 103 default: 104 break; 105 } 106 return TaskState::MAX; 107 }; 108 109 TaskState::RegisterOps(TaskState::READY, setState); 110 TaskState::RegisterOps(TaskState::RUNNING, setState); 111 TaskState::RegisterOps(TaskState::BLOCKED, setState); 112 TaskState::RegisterOps(TaskState::EXITED, setState); 113 114 task_attr_private task_attr; 115 task_attr.name_ = "root"; 116 auto root = std::make_unique<SCPUEUTask>( 117 &task_attr, nullptr, 0); 118 for (int i = 1; i <= 1000; ++i) { 119 task_attr_private task_attr; 120 task_attr.name_ = "i"; 121 tasks.push(std::make_unique<SCPUEUTask>( 122 &task_attr, root.get(), i)); 123 } 124 125 while (!tasks.empty()) { 126 auto task = std::move(tasks.front()); 127 tasks.pop(); 128 129 auto state = getNextState(task->state()); 130 if (state == TaskState::MAX) { 131 continue; 132 } 133 134 produceStatus.emplace_back(state); 135 136 task->UpdateState(state); 137 138 #if (TASKSTAT_LOG_ENABLE == 1) 139 auto preState = task->state.PreState(); 140 auto curState = task->state.CurState(); 141 142 decreCount(preState); 143 increCount(curState); 144 145 EXPECT_EQ(expectCount[static_cast<size_t>(preState)], TaskManager::Instance().GetCount(preState)); 146 EXPECT_EQ(expectCount[static_cast<size_t>(curState)], TaskManager::Instance().GetCount(curState)); 147 #endif 148 149 tasks.push(std::move(task)); 150 } 151 152 #if (TRACE_TASKSTAT_LOG_ENABLE == 1) 153 EXPECT_EQ( 154 expectCount[static_cast<size_t>(TaskState::PENDING)], TaskManager::Instance().GetCount(TaskState::PENDING)); 155 EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::READY)], TaskManager::Instance().GetCount(TaskState::READY)); 156 EXPECT_EQ( 157 expectCount[static_cast<size_t>(TaskState::RUNNING)], TaskManager::Instance().GetCount(TaskState::RUNNING)); 158 EXPECT_EQ( 159 expectCount[static_cast<size_t>(TaskState::BLOCKED)], TaskManager::Instance().GetCount(TaskState::BLOCKED)); 160 EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::EXITED)], TaskManager::Instance().GetCount(TaskState::EXITED)); 161 #endif 162 163 EXPECT_EQ(produceStatus.size(), consumeStatus.size()); 164 165 int size = produceStatus.size(); 166 for (int i = 0; i < size; ++i) { 167 EXPECT_EQ(produceStatus[i], consumeStatus[i]); 168 } 169 } 170 171 HWTEST_F(SchedulerTest, ffrt_task_runqueue_test, TestSize.Level1) 172 { 173 ffrt::FIFOQueue *fifoqueue = new ffrt::FIFOQueue(); 174 int aimnum = 10; 175 SCPUEUTask task(nullptr, nullptr, 0, QoS(static_cast<int>(qos_user_interactive))); 176 for (int i = 0; i < aimnum ; i++) { 177 fifoqueue->EnQueue(&task); 178 } 179 EXPECT_EQ(fifoqueue->Size(), aimnum); 180 EXPECT_EQ(fifoqueue->Empty(), false); 181 delete fifoqueue; 182 }