• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gtest/gtest.h>
17 #ifndef WITH_NO_MOCKER
18 #include <mockcpp/mockcpp.hpp>
19 #endif
20 #include <thread>
21 #include <climits>
22 #include <cstring>
23 #define private public
24 #define protected public
25 #include "eu/worker_manager.h"
26 #include "eu/scpuworker_manager.h"
27 #include "eu/scpu_monitor.h"
28 #include "sched/task_scheduler.h"
29 #include "tm/scpu_task.h"
30 #include "sched/scheduler.h"
31 #undef private
32 #undef protected
33 #include "../common.h"
34 #include "cpp/ffrt_dynamic_graph.h"
35 #include "c/ffrt_dynamic_graph.h"
36 
37 using namespace testing;
38 #ifdef HWTEST_TESTING_EXT_ENABLE
39 using namespace testing::ext;
40 #endif
41 using namespace ffrt;
42 
43 namespace {
44 // 返回当前环境是软化还是硬化
CheckSoftwareEnv()45 bool CheckSoftwareEnv()
46 {
47     return (ffrt_hcs_get_capability(FFRT_HW_DYNAMIC_XPU_NORMAL) == 0) ? true : false;
48 }
49 }
50 
51 class WorkerManagerTest : public testing::Test {
52 protected:
SetUpTestCase()53     static void SetUpTestCase()
54     {
55     }
56 
TearDownTestCase()57     static void TearDownTestCase()
58     {
59     }
60 
SetUp()61     void SetUp() override
62     {
63     }
64 
TearDown()65     void TearDown() override
66     {
67     }
68 };
69 
70 HWTEST_F(WorkerManagerTest, IncWorkerTest, TestSize.Level1)
71 {
72     CPUWorkerManager* cm = new SCPUWorkerManager();
73     QoS* qos = new QoS(-1);
74     bool iw = cm->IncWorker(*qos);
75     EXPECT_FALSE(iw);
76 
77     delete qos;
78     delete cm;
79 }
80 
81 HWTEST_F(WorkerManagerTest, IncWorkerTest2, TestSize.Level1)
82 {
83     CPUWorkerManager* cm = new SCPUWorkerManager();
84     QoS* qos = new QoS(-1);
85     cm->tearDown = true;
86     bool iw2 = cm->IncWorker(*qos);
87     EXPECT_FALSE(iw2);
88 
89     delete qos;
90     delete cm;
91 }
92 
93 HWTEST_F(WorkerManagerTest, GetWorkerCountTest, TestSize.Level1)
94 {
95     CPUWorkerManager* cm = new SCPUWorkerManager();
96     QoS* qos = new QoS(2);
97     cm->GetWorkerCount(*qos);
98     EXPECT_EQ(cm->GetWorkerCount(*qos), 0);
99 
100     delete qos;
101     delete cm;
102 }
103 
104 HWTEST_F(WorkerManagerTest, JoinTGTest, TestSize.Level1)
105 {
106     CPUWorkerManager* cm = new SCPUWorkerManager();
107     QoS* qos = new QoS(ffrt::qos_deadline_request);
108     ThreadGroup* tg = cm->JoinTG(*qos);
109     EXPECT_NE(tg, nullptr);
110 
111     QoS* qos1 = new QoS(ffrt::qos_user_interactive);
112     ThreadGroup* tg1 = cm->JoinTG(*qos1);
113     EXPECT_EQ(tg1, nullptr);
114     delete cm;
115     delete qos;
116     delete qos1;
117 }
118 
119 HWTEST_F(WorkerManagerTest, LeaveTGTest, TestSize.Level1)
120 {
121     CPUWorkerManager* cm = new SCPUWorkerManager();
122     QoS* qos = new QoS(ffrt::qos_deadline_request);
123     bool ltg = cm->IncWorker(*qos);
124     EXPECT_TRUE(ltg);
125 #ifndef WITH_NO_MOCKER
126     MOCKER_CPP(&RTGCtrl::GetThreadGroup).stubs().will(returnValue(1));
127     MOCKER_CPP(&RTGCtrl::PutThreadGroup).stubs().will(returnValue(true));
128     MOCKER_CPP(&RTGCtrl::JoinThread).stubs().will(returnValue(true));
129     MOCKER_CPP(&RTGCtrl::RemoveThread).stubs().will(returnValue(true));
130 #endif
131     ThreadGroup* ltg1 = cm->JoinTG(*qos);
132     EXPECT_NE(ltg1, nullptr);
133 
134     cm->LeaveTG(*qos);
135 
136     delete qos;
137     delete cm;
138 #ifndef WITH_NO_MOCKER
139     GlobalMockObject::verify();
140 #endif
141 }
142 
GetTaskCountStub(const QoS & qos)143 int GetTaskCountStub(const QoS& qos)
144 {
145     return 1;
146 }
147 
148 /*
149  * 测试用例名称:CPUMonitorHandleTaskNotifyUltraConservativeTest
150  * 测试用例描述:ffrt保守调度策略
151  * 预置条件    :创建SCPUWorkerManager,策略设置为HandleTaskNotifyUltraConservative,GetTaskCount方法打桩为GetTaskCountStub
152  * 操作步骤    :调用SCPUWorkerManager的Notify方法
153  * 预期结果    :成功执行HandleTaskNotifyUltraConservative方法
154  */
155 HWTEST_F(WorkerManagerTest, CPUMonitorHandleTaskNotifyUltraConservativeTest, TestSize.Level1)
156 {
157     SCPUWorkerManager* manager = new SCPUWorkerManager();
158 
159     CpuMonitorOps monitorOps { // change monitor's notify handle strategy
160         std::bind(&SCPUWorkerManager::IncWorker, manager, std::placeholders::_1),
__anon053278130202() 161         [=] (const QoS& qos) {
162             WorkerCtrl& workerCtrl = manager->monitor->ctrlQueue[2];
163             workerCtrl.sleepingWorkerNum--;
164         },
165         std::bind(&GetTaskCountStub, std::placeholders::_1),
166         std::bind(&SCPUWorkerManager::GetWorkerCount, manager, std::placeholders::_1),
167         SCPUMonitor::HandleTaskNotifyUltraConservative,
168     };
169     manager->monitor->ops = std::move(monitorOps);
170     WorkerCtrl& workerCtrl = manager->monitor->ctrlQueue[2];
171     EXPECT_EQ(workerCtrl.executionNum, 0);
172 
173     manager->NotifyTaskAdded(QoS(2)); // task notify event
174     EXPECT_EQ(workerCtrl.executionNum, 1);
175 
176     manager->monitor->ctrlQueue[2].sleepingWorkerNum = 1;
177     manager->NotifyTaskAdded(QoS(2)); // task notify event
178     EXPECT_EQ(workerCtrl.sleepingWorkerNum, 0);
179     delete manager;
180 }
181 
182 HWTEST_F(WorkerManagerTest, CPUMonitorHandleTaskNotifyConservativeTest, TestSize.Level1)
183 {
184     SCPUWorkerManager* manager = new SCPUWorkerManager();
185 
186     CpuMonitorOps monitorOps { // change monitor's notify handle strategy
187         std::bind(&SCPUWorkerManager::IncWorker, manager, std::placeholders::_1),
__anon053278130302() 188         [=] (const QoS& qos) {
189             WorkerCtrl& workerCtrl = manager->monitor->ctrlQueue[2];
190             workerCtrl.sleepingWorkerNum--;
191         },
192         std::bind(&GetTaskCountStub, std::placeholders::_1),
193         std::bind(&SCPUWorkerManager::GetWorkerCount, manager, std::placeholders::_1),
194         SCPUMonitor::HandleTaskNotifyConservative,
195     };
196     manager->monitor->ops = std::move(monitorOps);
197     WorkerCtrl& workerCtrl = manager->monitor->ctrlQueue[2];
198     EXPECT_EQ(workerCtrl.executionNum, 0);
199 
200     manager->NotifyTaskAdded(QoS(2)); // task notify event
201     EXPECT_EQ(workerCtrl.executionNum, 1);
202 
203     manager->monitor->ctrlQueue[2].sleepingWorkerNum = 1;
204     manager->NotifyTaskAdded(QoS(2)); // task notify event
205     EXPECT_EQ(workerCtrl.sleepingWorkerNum, 0);
206 }
207 
208 HWTEST_F(WorkerManagerTest, CPUMonitorHandleTaskNotifyConservativeTest2, TestSize.Level1)
209 {
210     SCPUWorkerManager* manager = new SCPUWorkerManager();
211     TaskNotifyType::TASK_PICKED;
212 
213     CpuMonitorOps monitorOps { // change monitor's notify handle strategy
214         std::bind(&SCPUWorkerManager::IncWorker, manager, std::placeholders::_1),
__anon053278130402() 215         [=] (const QoS& qos) {
216             WorkerCtrl& workerCtrl = manager->monitor->ctrlQueue[2];
217             workerCtrl.sleepingWorkerNum--;
218         },
219         std::bind(&GetTaskCountStub, std::placeholders::_1),
220         std::bind(&SCPUWorkerManager::GetWorkerCount, manager, std::placeholders::_1),
221         std::bind(&SCPUMonitor::HandleTaskNotifyConservative,
222             std::placeholders::_1, std::placeholders::_2, TaskNotifyType::TASK_PICKED),
223     };
224     manager->monitor->ops = std::move(monitorOps);
225     WorkerCtrl& workerCtrl = manager->monitor->ctrlQueue[2];
226     EXPECT_EQ(workerCtrl.executionNum, 0);
227 
228     manager->NotifyTaskAdded(QoS(2)); // task notify event
229     EXPECT_EQ(workerCtrl.executionNum, 1);
230 
231     manager->monitor->ctrlQueue[2].sleepingWorkerNum = 1;
232     manager->NotifyTaskAdded(QoS(2)); // task notify event
233     EXPECT_EQ(workerCtrl.sleepingWorkerNum, 1);
234 }
235 
236 HWTEST_F(WorkerManagerTest, PickUpTaskBatch, TestSize.Level1)
237 {
238     if (!CheckSoftwareEnv()) {
239         return;
240     }
241 
242     CPUWorkerManager* manager = new SCPUWorkerManager();
243     CPUManagerStrategy* strategy = new CPUManagerStrategy();
244     SCPUEUTask* task1 = new SCPUEUTask(nullptr, nullptr, 0, QoS(qos(0)));
245     SCPUEUTask* task2 = new SCPUEUTask(nullptr, nullptr, 0, QoS(qos(0)));
246     CPUMonitor* monitor = manager->GetCPUMonitor();
247 
248     auto worker1 = strategy->CreateCPUWorker(QoS(qos(0)), manager);
249     auto worker2 = strategy->CreateCPUWorker(QoS(qos(0)), manager);
250 
251     monitor->WakeupDeepSleep(QoS(qos(0)), false);
252     monitor->WakeupDeepSleep(QoS(qos(0)), false);
253 
254     auto& sched1 = FFRTScheduler::Instance()->GetScheduler(worker1->GetQos());
255     auto& sched2 = FFRTScheduler::Instance()->GetScheduler(worker2->GetQos());
256 
257     EXPECT_EQ(sched1.WakeupTask(reinterpret_cast<CPUEUTask*>(task1)), 1);
258     EXPECT_EQ(sched2.WakeupTask(reinterpret_cast<CPUEUTask*>(task2)), 1);
259 
260     EXPECT_NE(manager->PickUpTaskBatch(worker1), nullptr);
261     EXPECT_NE(manager->PickUpTaskBatch(worker2), nullptr);
262 
263     delete manager;
264     delete worker1;
265     delete worker2;
266     delete task1;
267     delete task2;
268     delete strategy;
269 }