• 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 <list>
17 #include <vector>
18 #include <queue>
19 #include <thread>
20 #include <gtest/gtest.h>
21 #define private public
22 #define protected public
23 #include "ffrt_inner.h"
24 
25 #include "core/entity.h"
26 #include "sched/task_scheduler.h"
27 #include "sched/scheduler.h"
28 #include "core/task_attr_private.h"
29 #include "tm/scpu_task.h"
30 #include "sched/stask_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, ffrt_task_runqueue_test, TestSize.Level0)
60 {
61     ffrt::FIFOQueue *fifoqueue = new ffrt::FIFOQueue();
62     int aimnum = 10;
63     SCPUEUTask task(nullptr, nullptr, 0);
64     for (int i = 0; i < aimnum ; i++) {
65         fifoqueue->EnQueue(&task);
66     }
67     EXPECT_EQ(fifoqueue->Size(), aimnum);
68     EXPECT_EQ(fifoqueue->Empty(), false);
69     delete fifoqueue;
70 }
71 
72 /*
73  * 测试用例名称:ffrt_sched_local_push_pop
74  * 测试用例描述:TaskSchduler, 开启本地队列后push和pop
75  * 预置条件    :无
76  * 操作步骤    :1、初始化STaskScheduler
77                  2、push和pop任务
78  * 预期结果    :push和pop后的任务数量符合预期
79  */
80 HWTEST_F(SchedulerTest, ffrt_sched_local_push_pop, TestSize.Level0)
81 {
82     STaskScheduler scheduler;
83     scheduler.SetTaskSchedMode(TaskSchedMode::LOCAL_TASK_SCHED_MODE);
84 
85     int taskCount = 100;
86 
87     EXPECT_EQ(scheduler.GetGlobalTaskCnt(), 0);
88 
89     task_attr_private attr;
90     attr.notifyWorker_ = false;
91     for (int i = 0; i < taskCount; i++) {
92         TaskBase* task = new SCPUEUTask(&attr, nullptr, 0);
93         scheduler.PushTaskGlobal(task, false);
94     }
95 
96     EXPECT_EQ(scheduler.GetTotalTaskCnt(), taskCount);
97 
98     // 提交三个任务,保持worker不退出1秒
99     for (int i = 0; i < 3; i++) {
__anon539643200102() 100         submit([]() {
101             sleep(1);
102         });
103     }
104 
105     // 赋值tick,保证能够从全局队列拿任务
106     unsigned int tick = 0;
107     *(scheduler.GetWorkerTick()) = &tick;
108 
109     TaskBase* task = scheduler.PopTask();
110 
111     while (task != nullptr) {
112         delete task;
113         task = scheduler.PopTask();
114     }
115 
116     EXPECT_EQ(scheduler.GetLocalTaskCnt(), 0);
117 
118     ffrt::wait();
119 }
120 
121 /*
122  * 测试用例名称 : ffrt_sched_local_steal
123  * 测试用例描述 : TaskSchduler, 开启本地队列后偷任务
124  * 预置条件    :无
125  * 操作步骤     : 1.初始化STaskScheduler
126  *               2.push任务到localQueue后保存到本地队列容器中
127  *               3.调用PopTask触发偷取任务
128  * 预期结果    : 偷取任务成功
129  */
130 HWTEST_F(SchedulerTest, ffrt_sched_local_steal, TestSize.Level0)
131 {
132     STaskScheduler scheduler;
133     scheduler.SetTaskSchedMode(TaskSchedMode::LOCAL_TASK_SCHED_MODE);
134 
135     int taskCount = 10;
136 
137     SpmcQueue localQueue;
138     localQueue.Init(128);
139 
140     for (int i = 0; i < taskCount; i++) {
141         TaskBase* task = new SCPUEUTask(nullptr, nullptr, 0);
142         localQueue.PushTail(task);
143     }
144 
145     scheduler.localQueues.emplace(syscall(SYS_gettid) + 1, &localQueue);
146 
147     EXPECT_GE(scheduler.GetTotalTaskCnt(), taskCount);
148 
149     EXPECT_GE(scheduler.GetPriorityTaskCnt(), 0);
150 
151     TaskBase* task = scheduler.PopTask();
152 
153     while (task != nullptr) {
154         delete task;
155         task = scheduler.PopTask();
156     }
157 
158     EXPECT_EQ(scheduler.GetLocalTaskCnt(), 0);
159 }
160 
161 /*
162  * 测试用例名称:ffrt_sched_local_priority
163  * 测试用例描述:TaskSchduler, 开启本地队列后向优先槽推任务
164  * 预置条件    :无
165  * 操作步骤    :1、初始化STaskScheduler
166                  2、push任务到localQueue后保存到本地队列容器中
167                  3、调用PopTask触发偷取任务
168  * 预期结果    :偷取任务成功
169  */
170 HWTEST_F(SchedulerTest, ffrt_sched_local_priority, TestSize.Level0)
171 {
172     STaskScheduler scheduler;
173     scheduler.SetTaskSchedMode(TaskSchedMode::LOCAL_TASK_SCHED_MODE);
174 
175     int taskCount = 10;
176 
177     for (int i = 0; i < taskCount; i++) {
178         TaskBase* task = new SCPUEUTask(nullptr, nullptr, 0);
179         scheduler.PushTaskToPriorityStack(task);
180     }
181 
182     auto task = scheduler.PopTask();
183 
184     EXPECT_NE(task, nullptr);
185 
186     while (task != nullptr) {
187         delete task;
188         task = scheduler.PopTask();
189     }
190 
191     EXPECT_LE(scheduler.GetLocalTaskCnt(), 0);
192 }
193 
194 namespace {
PushTest(void * task)195     void PushTest(void* task) {
196         if (task != nullptr) {
197             delete reinterpret_cast<TaskBase*>(task);
198         }
199     }
200 }
201 
202 /*
203  * 测试用例名称:task_runqueue_pop_to_another_full_test
204  * 测试用例描述:SpmcQueue, 向另一个即将满任务的队列中push任务
205  * 预置条件    :无
206  * 操作步骤    :1、初始化两个队列,一个填10个,一个空间未初始化
207                  2、调用PopHeadToAnotherQueue向另一个队列中push任务
208  * 预期结果    :Push任务失败,原队列任务数量符合预期
209  */
210 HWTEST_F(SchedulerTest, task_runqueue_pop_to_another_fail_test, TestSize.Level0)
211 {
212     int taskCount = 10;
213     int localSize = 128;
214     SpmcQueue localQueue;
215     localQueue.Init(localSize);
216 
217     SpmcQueue anotherQueue;
218     anotherQueue.tail_ = 0;
219     anotherQueue.head_ = 0;
220     anotherQueue.capacity_ = localSize;
221 
222     for (int i = 0; i < taskCount; i++) {
223         TaskBase* task = new SCPUEUTask(nullptr, nullptr, 0);
224         localQueue.PushTail(task);
225     }
226 
227     int pushCount = localQueue.PopHeadToAnotherQueue(anotherQueue, taskCount, PushTest);
228 
229     EXPECT_EQ(localQueue.GetLength(), taskCount - 1);
230     EXPECT_EQ(anotherQueue.GetLength(), 0);
231     EXPECT_EQ(pushCount, 0);
232 
233     auto task = anotherQueue.PopHead();
234     while (task != nullptr) {
235         delete reinterpret_cast<TaskBase*>(task);
236         task = anotherQueue.PopHead();
237     }
238 }
239 
240 HWTEST_F(SchedulerTest, sched_test, TestSize.Level1)
241 {
242     STaskScheduler* scheduler = new STaskScheduler();
243     scheduler->SetTaskSchedMode(TaskSchedMode::LOCAL_TASK_SCHED_MODE);
244     ffrt_executor_task_t work = {};
245     bool ret = scheduler->CancelUVWork(&work);
246 #ifndef FFRT_GITEE
247     EXPECT_EQ(ret, true);
248 #endif
249     ffrt::TaskBase* task = new ffrt::SCPUEUTask(nullptr, nullptr, 0);
250     scheduler->PushTask(task);
251     scheduler->GetPriorityTaskCnt();
252     scheduler->PushTaskLocalOrPriority(task);
253     delete scheduler;
254 }
255