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 #ifndef FFRT_WORKER_THREAD_HPP 17 #define FFRT_WORKER_THREAD_HPP 18 19 #include <atomic> 20 #ifdef FFRT_PTHREAD_ENABLE 21 #include <pthread.h> 22 #endif 23 #ifdef OHOS_THREAD_STACK_DUMP 24 #include <sstream> 25 #include "dfx_dump_catcher.h" 26 #endif 27 28 #include "qos.h" 29 #include "tm/cpu_task.h" 30 31 namespace ffrt { 32 class WorkerThread { 33 public: 34 CPUEUTask* curTask = nullptr; 35 explicit WorkerThread(const QoS& qos); 36 ~WorkerThread()37 virtual ~WorkerThread() 38 { 39 if (!exited) { 40 #ifdef OHOS_THREAD_STACK_DUMP 41 OHOS::HiviewDFX::DfxDumpCatcher dumplog; 42 std::string msg = ""; 43 bool result = dumplog.DumpCatch(getpid(), gettid(), msg); 44 if (result) { 45 std::vector<std::string> out; 46 std::stringstream ss(msg); 47 std::string s; 48 while (std::getline(ss, s, '\n')) { 49 out.push_back(s); 50 } 51 for (auto const& line: out) { 52 FFRT_LOGE("ffrt callstack %{public}s", line.c_str()); 53 } 54 } 55 #endif 56 } 57 Detach(); 58 } 59 Idle()60 bool Idle() const 61 { 62 return idle; 63 } 64 SetIdle(bool var)65 void SetIdle(bool var) 66 { 67 this->idle = var; 68 } 69 Exited()70 bool Exited() const 71 { 72 return exited; 73 } 74 SetExited(bool var)75 void SetExited(bool var) 76 { 77 this->exited = var; 78 } 79 Id()80 pid_t Id() const 81 { 82 while (!exited && tid < 0) { 83 } 84 return tid; 85 } 86 GetQos()87 const QoS& GetQos() const 88 { 89 return qos; 90 } 91 #ifdef FFRT_PTHREAD_ENABLE Start(void * (* ThreadFunc)(void *),void * args)92 void Start(void*(*ThreadFunc)(void*), void* args) 93 { 94 int ret = pthread_create(&thread_, &attr_, ThreadFunc, args); 95 if (ret != 0) { 96 exited = true; 97 } 98 pthread_attr_destroy(&attr_); 99 } 100 Join()101 void Join() 102 { 103 if (tid > 0) { 104 pthread_join(thread_, nullptr); 105 } 106 tid = -1; 107 } 108 Detach()109 void Detach() 110 { 111 if (tid > 0) { 112 pthread_detach(thread_); 113 } else { 114 FFRT_LOGI("qos %d thread not joinable.", qos()); 115 } 116 tid = -1; 117 } 118 GetThread()119 pthread_t& GetThread() 120 { 121 return this->thread_; 122 } 123 #else 124 template <typename F, typename... Args> Start(F && f,Args &&...args)125 void Start(F&& f, Args&&... args) 126 { 127 auto wrap = [&](Args&&... args) { 128 NativeConfig(); 129 return f(args...); 130 }; 131 thread = std::thread(wrap, args...); 132 } 133 Join()134 void Join() 135 { 136 if (thread.joinable()) { 137 thread.join(); 138 } 139 tid = -1; 140 } 141 Detach()142 void Detach() 143 { 144 if (thread.joinable()) { 145 thread.detach(); 146 } else { 147 FFRT_LOGI("qos %d thread not joinable\n", qos()); 148 } 149 tid = -1; 150 } 151 GetThread()152 pthread_t GetThread() 153 { 154 return this->thread.native_handle(); 155 } 156 #endif 157 158 void WorkerSetup(WorkerThread* wthread); 159 void NativeConfig(); 160 161 private: 162 std::atomic_bool exited; 163 std::atomic_bool idle; 164 165 std::atomic<pid_t> tid; 166 167 QoS qos; 168 #ifdef FFRT_PTHREAD_ENABLE 169 pthread_t thread_; 170 pthread_attr_t attr_; 171 #else 172 std::thread thread; 173 #endif 174 }; 175 void SetThreadAttr(WorkerThread* thread, const QoS& qos); 176 } // namespace ffrt 177 #endif 178