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 virtual void SetUp()
51 {
52 }
53
TearDown()54 virtual void TearDown()
55 {
56 }
57 };
58
HWTEST_F(SchedulerTest, taskstate_test, TestSize.Level1)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
80 auto increCount = [&expectCount](TaskState::State state) { ++expectCount[static_cast<size_t>(state)]; };
81
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
88 auto setState = [&](CPUEUTask* task) {
89 consumeStatus.emplace_back(task->state());
90 return true;
91 };
92
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
HWTEST_F(SchedulerTest, taskstateCount_test, TestSize.Level1)171 HWTEST_F(SchedulerTest, taskstateCount_test, TestSize.Level1)
172 {
173 SCPUEUTask* task1 = new SCPUEUTask(nullptr, nullptr, 0, QoS(static_cast<int>(qos_user_interactive)));
174 SCPUEUTask *task2 = new SCPUEUTask(nullptr, task1, 0, QoS());
175 TaskManager::Instance().TaskStateCount(task2);
176 }
177
HWTEST_F(SchedulerTest, ffrt_task_runqueue_test, TestSize.Level1)178 HWTEST_F(SchedulerTest, ffrt_task_runqueue_test, TestSize.Level1)
179 {
180 ffrt::FIFOQueue *fifoqueue = new ffrt::FIFOQueue();
181 int aimnum = 10;
182 for (int i = 0; i < aimnum ; i++) {
183 SCPUEUTask* task = new SCPUEUTask(nullptr, nullptr, 0, QoS(static_cast<int>(qos_user_interactive)));
184 fifoqueue->EnQueue(task);
185 }
186 EXPECT_EQ(fifoqueue->Size(), aimnum);
187 EXPECT_EQ(fifoqueue->Empty(), false);
188 }
189
HWTEST_F(SchedulerTest, ffrt_scheduler_test, TestSize.Level1)190 HWTEST_F(SchedulerTest, ffrt_scheduler_test, TestSize.Level1)
191 {
192 ffrt::SFFRTScheduler *sffrtscheduler = new ffrt::SFFRTScheduler();
193 LinkedList* node = new LinkedList();
194 QoS qos;
195 EXPECT_EQ(sffrtscheduler->InsertNode(node, qos), true);
196 EXPECT_EQ(sffrtscheduler->RemoveNode(node, qos), true);
197
198 delete node;
199 }
200