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