1 /* 2 * Copyright (C) 2024 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 SKIA_TASK_EXECUTOR_H 17 #define SKIA_TASK_EXECUTOR_H 18 19 #include <condition_variable> 20 #include <functional> 21 #include <mutex> 22 #include <pthread.h> 23 #include <string> 24 #include <thread> 25 #include <unistd.h> 26 #include <utility> 27 #ifdef RES_SCHED_ENABLE 28 #include "rs_frame_report.h" 29 #endif 30 31 #ifdef _WIN32 32 #include <windows.h> 33 #define gettid GetCurrentThreadId 34 #endif 35 36 #ifdef __APPLE__ 37 #define gettid getpid 38 #endif 39 40 #ifdef __gnu_linux__ 41 #include <sys/syscall.h> 42 #include <sys/types.h> 43 #define gettid []()->int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); } 44 #endif 45 46 namespace OHOS { 47 namespace Rosen { 48 49 template<class T, uint32_t SIZE> 50 class TaskQueue { 51 public: 52 TaskQueue() = default; 53 ~TaskQueue() = default; 54 Push(T && t)55 constexpr void Push(T&& t) 56 { 57 uint32_t newHead = (head_ + 1) % SIZE; 58 if (newHead == tail_) { 59 return; 60 } 61 buffer_[head_] = std::move(t); 62 head_ = newHead; 63 } 64 Pop()65 constexpr T Pop() 66 { 67 if (tail_ == head_) { 68 return nullptr; 69 } 70 uint32_t index = tail_; 71 tail_ = (tail_ + 1) % SIZE; 72 T t = std::move(buffer_[index]); 73 buffer_[index] = nullptr; 74 return t; 75 } 76 HasTask()77 constexpr bool HasTask() const 78 { 79 return head_ != tail_; 80 } 81 HasSpace()82 constexpr bool HasSpace() const 83 { 84 return ((head_ + 1) % SIZE) != tail_; 85 } 86 Size()87 constexpr uint32_t Size() const 88 { 89 if (head_ > tail_) { 90 return head_ - tail_; 91 } else { 92 return tail_ - head_ + SIZE; 93 } 94 } 95 96 private: 97 TaskQueue(const TaskQueue&) = delete; 98 void operator=(const TaskQueue&) = delete; 99 T buffer_[SIZE]; 100 uint32_t head_ = 0; 101 uint32_t tail_ = 0; 102 }; 103 104 class TaskPoolExecutor { 105 public: 106 using Task = std::function<void()>; 107 static void PostTask(Task&& task); 108 109 private: 110 TaskPoolExecutor(const TaskPoolExecutor&) = delete; 111 void operator=(const TaskPoolExecutor&) = delete; 112 113 static TaskPoolExecutor& GetInstance(); 114 115 TaskPoolExecutor(); ~TaskPoolExecutor()116 ~TaskPoolExecutor() {} 117 118 void InitThreadPool(); 119 120 void EnqueueTask(Task&& task); 121 #ifdef RES_SCHED_ENABLE 122 void PromoteThreadPriority(); 123 #endif 124 void ThreadLoop(); 125 126 #ifdef RES_SCHED_ENABLE 127 static constexpr uint32_t REQUEST_THREAD_PRIORITY_ID = 100005; 128 static constexpr uint32_t REQUEST_THREAD_PRIORITY_LOAD = 0; 129 static constexpr uint32_t REQUEST_THREAD_PRIORITY_NUM = 0; 130 #endif 131 static constexpr uint32_t DEFAULT_THREAD_COUNT = 2; 132 static constexpr uint32_t QUEUE_SIZE = 512; 133 static constexpr uint32_t WAIT_SLEEP_TIME = 100; 134 std::mutex mutex_; 135 std::condition_variable condition_; 136 uint32_t waitingThread_ = 0; 137 bool running_ = true; 138 TaskQueue<Task, QUEUE_SIZE> taskQueue_; 139 }; 140 } // namespace Rosen 141 } // namespace OHOS 142 #endif