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