• 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 "libpandabase/taskmanager/task_scheduler.h"
17 #include "libpandabase/os/thread.h"
18 
19 namespace panda::taskmanager {
20 
WorkerThread(FinishedTasksCallback callback,size_t tasksCount)21 WorkerThread::WorkerThread(FinishedTasksCallback callback, size_t tasksCount)
22     : finishedTasksCallback_(std::move(callback))
23 {
24     thread_ = new std::thread(&WorkerThread::WorkerLoop, this, tasksCount);
25     os::thread::SetThreadName(thread_->native_handle(), "TaskSchedulerWorker");
26 }
27 
AddTask(Task && task)28 void WorkerThread::AddTask(Task &&task)
29 {
30     if (task.GetTaskProperties().GetTaskExecutionMode() == TaskExecutionMode::FOREGROUND) {
31         foregroundQueue_.push(std::move(task));
32     } else {
33         backgroundQueue_.push(std::move(task));
34     }
35     size_++;
36 }
37 
PopTask()38 Task WorkerThread::PopTask()
39 {
40     ASSERT(!IsEmpty());
41     std::queue<Task> *queue = nullptr;
42     if (!foregroundQueue_.empty()) {
43         queue = &foregroundQueue_;
44     } else {
45         queue = &backgroundQueue_;
46     }
47     auto task = std::move(queue->front());
48     queue->pop();
49     size_--;
50     return task;
51 }
52 
Join()53 void WorkerThread::Join()
54 {
55     thread_->join();
56 }
57 
IsEmpty() const58 bool WorkerThread::IsEmpty() const
59 {
60     return size_ == 0;
61 }
62 
WorkerLoop(size_t tasksCount)63 void WorkerThread::WorkerLoop(size_t tasksCount)
64 {
65     while (true) {
66         auto finishCond = TaskScheduler::GetTaskScheduler()->FillWithTasks(this, tasksCount);
67         ExecuteTasks();
68         if (finishCond) {
69             break;
70         }
71         finishedTasksCallback_(finishedTasksCounterMap_);
72         finishedTasksCounterMap_.clear();
73     }
74 }
75 
ExecuteTasks()76 void WorkerThread::ExecuteTasks()
77 {
78     while (!IsEmpty()) {
79         auto task = PopTask();
80         task.RunTask();
81         finishedTasksCounterMap_[task.GetTaskProperties()]++;
82     }
83 }
84 
~WorkerThread()85 WorkerThread::~WorkerThread()
86 {
87     delete thread_;
88 }
89 
90 }  // namespace panda::taskmanager
91