• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 #ifndef PANDA_LIBPANDABASE_TASKMANAGER_WORKER_THREAD_H
17 #define PANDA_LIBPANDABASE_TASKMANAGER_WORKER_THREAD_H
18 
19 #include "libpandabase/taskmanager/schedulable_task_queue_interface.h"
20 #include "libpandabase/taskmanager/utils/two_lock_queue.h"
21 #include "libpandabase/os/mutex.h"
22 #include <thread>
23 
24 namespace ark::taskmanager::internal {
25 
26 class TaskScheduler;
27 class TaskQueueSet;
28 
29 class WorkerThread {
30 public:
31     NO_COPY_SEMANTIC(WorkerThread);
32     NO_MOVE_SEMANTIC(WorkerThread);
33 
34     static constexpr size_t WORKER_QUEUE_SIZE = 4UL;
35 
36     WorkerThread(TaskScheduler *scheduler, TaskTimeStatsBase *taskTimeStats, const std::string &name);
37     ~WorkerThread();
38 
39     void AddForegroundTask(TaskPtr task);
40     void AddBackgroundTask(TaskPtr task);
41     /// @brief Returns true if all internal queues are empty
42     bool IsEmpty() const;
43     /// @brief Returns count of tasks in local queue
44     size_t Size() const;
45 
46     TaskPtr PopTask();
47     TaskPtr PopForegroundTask();
48     TaskPtr PopBackgroundTask();
49     /// @brief Waits for worker finish
50     void Join();
51 
52     std::string GetWorkerName() const;
53     /// @brief method starts WorkerLoop. All workers should be registered before Start executing
54     void Start();
55 
SetFinish()56     void SetFinish()
57     {
58         // Atomic with relaxed order reason: no order requirement
59         finish_.store(true, std::memory_order_relaxed);
60     }
61 
CheckFinish()62     bool CheckFinish() const
63     {
64         // Atomic with relaxed order reason: no order requirement
65         return finish_.load(std::memory_order_relaxed);
66     }
67 
68 private:
69     /// @brief Main workers algorithm
70     void WorkerLoop();
71     /**
72      * @brief pops and executes all tasks from internal queue.
73      * Also counts executed tasks in finishedTasksCounterMap_.
74      */
75     size_t ExecuteTasksFromLocalQueue();
76     /**
77      * @brief method wait for starting
78      * @see Start
79      */
80     void WaitForStart();
81 
82     using SelfTaskQueue = TwoLockQueue<TaskPtr, std::allocator<TaskPtr>>;
83     SelfTaskQueue foregroundTaskQueue_;
84     SelfTaskQueue backgroundTaskQueue_;
85     std::thread *thread_ = nullptr;
86     TaskScheduler *scheduler_ = nullptr;
87     TaskTimeStatsBase *taskTimeStats_ = nullptr;
88     std::string name_;
89     os::memory::Mutex startWaitLock_;
90     os::memory::ConditionVariable startWaitCondVar_ GUARDED_BY(startWaitLock_);
91     bool start_ {false};
92     std::atomic_bool finish_ {false};
93 };
94 
95 }  // namespace ark::taskmanager::internal
96 
97 #endif  // PANDA_LIBPANDABASE_TASKMANAGER_WORKER_THREAD_H
98