• 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 #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