• 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 #include "c/queue_ext.h"
16 #include "cpp/queue.h"
17 #include "util/event_handler_adapter.h"
18 #include "dm/dependence_manager.h"
19 #include "tm/queue_task.h"
20 #include "queue_handler.h"
21 
22 using namespace std;
23 using namespace ffrt;
24 
25 namespace {
ResetTimeoutCb(ffrt::queue_attr_private * p)26 inline void ResetTimeoutCb(ffrt::queue_attr_private* p)
27 {
28     if (p->timeoutCb_ == nullptr) {
29         return;
30     }
31     QueueTask* cbTask = GetQueueTaskByFuncStorageOffset(p->timeoutCb_);
32     cbTask->DecDeleteRef();
33     p->timeoutCb_ = nullptr;
34 }
35 
ffrt_queue_submit_base(ffrt_queue_t queue,ffrt_function_header_t * f,bool withHandle,bool insertHead,const ffrt_task_attr_t * attr)36 inline QueueTask* ffrt_queue_submit_base(ffrt_queue_t queue, ffrt_function_header_t* f, bool withHandle,
37     bool insertHead, const ffrt_task_attr_t* attr)
38 {
39     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return nullptr, "input invalid, queue == nullptr");
40     FFRT_COND_DO_ERR(unlikely(f == nullptr), return nullptr, "input invalid, function header == nullptr");
41     QueueHandler* handler = static_cast<QueueHandler*>(queue);
42     ffrt::task_attr_private *p = reinterpret_cast<ffrt::task_attr_private *>(const_cast<ffrt_task_attr_t *>(attr));
43     QueueTask* task = GetQueueTaskByFuncStorageOffset(f);
44     new (task)ffrt::QueueTask(handler, p, insertHead);
45     if (withHandle) {
46         task->IncDeleteRef();
47     }
48 
49     handler->Submit(task);
50     return task;
51 }
52 } // namespace
53 
54 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_init(ffrt_queue_attr_t * attr)55 int ffrt_queue_attr_init(ffrt_queue_attr_t* attr)
56 {
57     FFRT_COND_DO_ERR((attr == nullptr), return -1, "input invalid, attr == nullptr");
58     static_assert(sizeof(ffrt::queue_attr_private) <= ffrt_queue_attr_storage_size,
59         "size must be less than ffrt_queue_attr_storage_size");
60 
61     new (attr) ffrt::queue_attr_private();
62     return 0;
63 }
64 
65 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_destroy(ffrt_queue_attr_t * attr)66 void ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr)
67 {
68     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
69     auto p = reinterpret_cast<ffrt::queue_attr_private*>(attr);
70     ResetTimeoutCb(p);
71     p->~queue_attr_private();
72 }
73 
74 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_set_qos(ffrt_queue_attr_t * attr,ffrt_qos_t qos)75 void ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos)
76 {
77     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
78 
79     (reinterpret_cast<ffrt::queue_attr_private*>(attr))->qos_ = ffrt::GetFuncQosMap()(qos);
80 }
81 
82 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_get_qos(const ffrt_queue_attr_t * attr)83 ffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr)
84 {
85     FFRT_COND_DO_ERR((attr == nullptr), return ffrt_qos_default, "input invalid, attr == nullptr");
86     ffrt_queue_attr_t* p = const_cast<ffrt_queue_attr_t*>(attr);
87     return (reinterpret_cast<ffrt::queue_attr_private*>(p))->qos_;
88 }
89 
90 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_set_timeout(ffrt_queue_attr_t * attr,uint64_t timeout_us)91 void ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us)
92 {
93     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
94     (reinterpret_cast<ffrt::queue_attr_private*>(attr))->timeout_ = timeout_us;
95 }
96 
97 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t * attr)98 uint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr)
99 {
100     FFRT_COND_DO_ERR((attr == nullptr), return 0, "input invalid, attr == nullptr");
101     ffrt_queue_attr_t* p = const_cast<ffrt_queue_attr_t*>(attr);
102     return (reinterpret_cast<ffrt::queue_attr_private*>(p))->timeout_;
103 }
104 
105 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_set_callback(ffrt_queue_attr_t * attr,ffrt_function_header_t * f)106 void ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f)
107 {
108     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
109     FFRT_COND_DO_ERR((f == nullptr), return, "input invalid, f == nullptr");
110     ffrt::queue_attr_private* p = reinterpret_cast<ffrt::queue_attr_private*>(attr);
111     ResetTimeoutCb(p);
112     p->timeoutCb_ = f;
113     // the memory of timeoutCb are managed in the form of QueueTask
114     QueueTask* task = GetQueueTaskByFuncStorageOffset(f);
115     new (task)ffrt::QueueTask(nullptr);
116 }
117 
118 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_get_callback(const ffrt_queue_attr_t * attr)119 ffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr)
120 {
121     FFRT_COND_DO_ERR((attr == nullptr), return nullptr, "input invalid, attr == nullptr");
122     ffrt_queue_attr_t* p = const_cast<ffrt_queue_attr_t*>(attr);
123     return (reinterpret_cast<ffrt::queue_attr_private*>(p))->timeoutCb_;
124 }
125 
126 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_set_max_concurrency(ffrt_queue_attr_t * attr,const int max_concurrency)127 void ffrt_queue_attr_set_max_concurrency(ffrt_queue_attr_t* attr, const int max_concurrency)
128 {
129     FFRT_COND_DO_ERR((attr == nullptr), return, "input invalid, attr == nullptr");
130 
131     FFRT_COND_DO_ERR((max_concurrency <= 0), return,
132         "max concurrency should be a valid value");
133 
134     (reinterpret_cast<ffrt::queue_attr_private*>(attr))->maxConcurrency_ = max_concurrency;
135 }
136 
137 API_ATTRIBUTE((visibility("default")))
ffrt_queue_attr_get_max_concurrency(const ffrt_queue_attr_t * attr)138 int ffrt_queue_attr_get_max_concurrency(const ffrt_queue_attr_t* attr)
139 {
140     FFRT_COND_DO_ERR((attr == nullptr), return 0, "input invalid, attr == nullptr");
141     ffrt_queue_attr_t* p = const_cast<ffrt_queue_attr_t*>(attr);
142     return (reinterpret_cast<ffrt::queue_attr_private*>(p))->maxConcurrency_;
143 }
144 
145 API_ATTRIBUTE((visibility("default")))
ffrt_queue_create(ffrt_queue_type_t type,const char * name,const ffrt_queue_attr_t * attr)146 ffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr)
147 {
148     bool invalidType = (type == ffrt_queue_max) || (type < ffrt_queue_serial) ||
149         (type >= static_cast<ffrt_queue_type_t>(ffrt_queue_inner_max));
150     FFRT_COND_DO_ERR(invalidType, return nullptr, "input invalid, type unsupport");
151     QueueHandler* handler = new (std::nothrow) QueueHandler(name, attr, type);
152     FFRT_COND_DO_ERR((handler == nullptr), return nullptr, "failed to construct QueueHandler");
153     return static_cast<ffrt_queue_t>(handler);
154 }
155 
156 API_ATTRIBUTE((visibility("default")))
ffrt_queue_destroy(ffrt_queue_t queue)157 void ffrt_queue_destroy(ffrt_queue_t queue)
158 {
159     FFRT_COND_DO_ERR((queue == nullptr), return, "input invalid, queue is nullptr");
160     QueueHandler* handler = static_cast<QueueHandler*>(queue);
161     delete handler;
162 }
163 
164 API_ATTRIBUTE((visibility("default")))
ffrt_queue_submit(ffrt_queue_t queue,ffrt_function_header_t * f,const ffrt_task_attr_t * attr)165 void ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
166 {
167     FFRT_COND_DO_ERR((f == nullptr), return, "input invalid, function is nullptr");
168     QueueTask* task = ffrt_queue_submit_base(queue, f, false, false, attr);
169     FFRT_COND_DO_ERR((task == nullptr), return, "failed to submit serial task");
170 }
171 
172 API_ATTRIBUTE((visibility("default")))
ffrt_queue_submit_head(ffrt_queue_t queue,ffrt_function_header_t * f,const ffrt_task_attr_t * attr)173 void ffrt_queue_submit_head(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
174 {
175     FFRT_COND_DO_ERR((f == nullptr), return, "input invalid, function is nullptr");
176     QueueTask* task = ffrt_queue_submit_base(queue, f, false, true, attr);
177     FFRT_COND_DO_ERR((task == nullptr), return, "failed to submit serial task");
178 }
179 
180 API_ATTRIBUTE((visibility("default")))
ffrt_queue_submit_h(ffrt_queue_t queue,ffrt_function_header_t * f,const ffrt_task_attr_t * attr)181 ffrt_task_handle_t ffrt_queue_submit_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
182 {
183     FFRT_COND_DO_ERR((f == nullptr), return nullptr, "input invalid, function is nullptr");
184     QueueTask* task = ffrt_queue_submit_base(queue, f, true, false, attr);
185     FFRT_COND_DO_ERR((task == nullptr), return nullptr, "failed to submit serial task");
186     return static_cast<ffrt_task_handle_t>(task);
187 }
188 
189 API_ATTRIBUTE((visibility("default")))
ffrt_queue_submit_head_h(ffrt_queue_t queue,ffrt_function_header_t * f,const ffrt_task_attr_t * attr)190 ffrt_task_handle_t ffrt_queue_submit_head_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
191 {
192     FFRT_COND_DO_ERR((f == nullptr), return nullptr, "input invalid, function is nullptr");
193     QueueTask* task = ffrt_queue_submit_base(queue, f, true, true, attr);
194     FFRT_COND_DO_ERR((task == nullptr), return nullptr, "failed to submit serial task");
195     return static_cast<ffrt_task_handle_t>(task);
196 }
197 
198 API_ATTRIBUTE((visibility("default")))
ffrt_queue_wait(ffrt_task_handle_t handle)199 void ffrt_queue_wait(ffrt_task_handle_t handle)
200 {
201     FFRT_COND_DO_ERR((handle == nullptr), return, "input invalid, task_handle is nullptr");
202     QueueTask* task = static_cast<QueueTask*>(handle);
203     task->Wait();
204 }
205 
206 API_ATTRIBUTE((visibility("default")))
ffrt_queue_get_task_cnt(ffrt_queue_t queue)207 uint64_t ffrt_queue_get_task_cnt(ffrt_queue_t queue)
208 {
209     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return 0, "input invalid, queue == nullptr");
210     QueueHandler* handler = static_cast<QueueHandler*>(queue);
211     return handler->GetTaskCnt();
212 }
213 
214 API_ATTRIBUTE((visibility("default")))
ffrt_queue_cancel(ffrt_task_handle_t handle)215 int ffrt_queue_cancel(ffrt_task_handle_t handle)
216 {
217     FFRT_COND_DO_ERR((handle == nullptr), return -1, "input invalid, handle is nullptr");
218     QueueTask* task = reinterpret_cast<QueueTask*>(static_cast<CPUEUTask*>(handle));
219     QueueHandler* handler = task->GetHandler();
220     FFRT_COND_DO_ERR((handler == nullptr), return -1, "task handler is nullptr");
221     int ret = handler->Cancel(task);
222     return ret;
223 }
224 
225 API_ATTRIBUTE((visibility("default")))
ffrt_queue_cancel_all(ffrt_queue_t queue)226 void ffrt_queue_cancel_all(ffrt_queue_t queue)
227 {
228     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return, "input invalid, queue is nullptr");
229     QueueHandler* handler = static_cast<QueueHandler*>(queue);
230     handler->Cancel();
231 }
232 
233 API_ATTRIBUTE((visibility("default")))
ffrt_queue_cancel_and_wait(ffrt_queue_t queue)234 void ffrt_queue_cancel_and_wait(ffrt_queue_t queue)
235 {
236     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return, "input invalid, queue is nullptr");
237     QueueHandler* handler = static_cast<QueueHandler*>(queue);
238     handler->CancelAndWait();
239 }
240 
241 API_ATTRIBUTE((visibility("default")))
ffrt_queue_cancel_by_name(ffrt_queue_t queue,const char * name)242 int ffrt_queue_cancel_by_name(ffrt_queue_t queue, const char* name)
243 {
244     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return -1, "input invalid, queue is nullptr");
245     FFRT_COND_DO_ERR(unlikely(name == nullptr), return -1, "input invalid, name is nullptr");
246     QueueHandler* handler = static_cast<QueueHandler*>(queue);
247     return handler->Cancel(name);
248 }
249 
250 API_ATTRIBUTE((visibility("default")))
ffrt_queue_has_task(ffrt_queue_t queue,const char * name)251 bool ffrt_queue_has_task(ffrt_queue_t queue, const char* name)
252 {
253     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return false, "input invalid, queue is nullptr");
254     FFRT_COND_DO_ERR(unlikely(name == nullptr), return false, "input invalid, name is nullptr");
255     QueueHandler* handler = static_cast<QueueHandler*>(queue);
256     return handler->HasTask(name);
257 }
258 
259 API_ATTRIBUTE((visibility("default")))
ffrt_queue_is_idle(ffrt_queue_t queue)260 bool ffrt_queue_is_idle(ffrt_queue_t queue)
261 {
262     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return false, "input invalid, queue is nullptr");
263     QueueHandler* handler = static_cast<QueueHandler*>(queue);
264     return handler->IsIdle();
265 }
266 
267 API_ATTRIBUTE((visibility("default")))
ffrt_queue_set_eventhandler(ffrt_queue_t queue,void * eventhandler)268 void ffrt_queue_set_eventhandler(ffrt_queue_t queue, void* eventhandler)
269 {
270     FFRT_COND_DO_ERR(unlikely(queue == nullptr), return, "input invalid, queue is nullptr");
271     QueueHandler* handler = static_cast<QueueHandler*>(queue);
272     handler->SetEventHandler(eventhandler);
273 }
274 
275 API_ATTRIBUTE((visibility("default")))
ffrt_get_current_queue_eventhandler(void)276 void* ffrt_get_current_queue_eventhandler(void)
277 {
278     CPUEUTask* curTask = ffrt::ExecuteCtx::Cur()->task;
279     if (curTask == nullptr || curTask->type != ffrt_queue_task) {
280         FFRT_LOGW("Current task is nullptr or is not a serial task.");
281         return nullptr;
282     }
283 
284     QueueHandler* handler = reinterpret_cast<QueueTask*>(curTask)->GetHandler();
285     FFRT_COND_DO_ERR((handler == nullptr), return nullptr, "task handler is nullptr");
286     return handler->GetEventHandler();
287 }
288 
289 API_ATTRIBUTE((visibility("default")))
ffrt_get_main_queue(void)290 ffrt_queue_t ffrt_get_main_queue(void)
291 {
292     FFRT_COND_DO_ERR((EventHandlerAdapter::Instance()->GetMainEventHandler == nullptr),
293         return nullptr, "failed to load GetMainEventHandler Func.");
294     static QueueHandler handler = QueueHandler("main_queue", nullptr, ffrt_queue_eventhandler_interactive);
295     if (!handler.GetEventHandler()) {
296         void* mainHandler = EventHandlerAdapter::Instance()->GetMainEventHandler();
297         FFRT_COND_DO_ERR((mainHandler == nullptr), return nullptr, "failed to get main queue.");
298         handler.SetEventHandler(mainHandler);
299     }
300     return static_cast<ffrt_queue_t>(&handler);
301 }
302 
303 API_ATTRIBUTE((visibility("default")))
ffrt_get_current_queue(void)304 ffrt_queue_t ffrt_get_current_queue(void)
305 {
306     FFRT_COND_DO_ERR((EventHandlerAdapter::Instance()->GetCurrentEventHandler == nullptr),
307         return nullptr, "failed to load GetCurrentEventHandler Func.");
308     void* workerHandler = EventHandlerAdapter::Instance()->GetCurrentEventHandler();
309     FFRT_COND_DO_ERR((workerHandler == nullptr), return nullptr, "failed to get ArkTs worker queue.");
310     QueueHandler *handler = new (std::nothrow) QueueHandler(
311         "current_queue", nullptr, ffrt_queue_eventhandler_interactive);
312     FFRT_COND_DO_ERR((handler == nullptr), return nullptr, "failed to construct WorkerThreadQueueHandler");
313     handler->SetEventHandler(workerHandler);
314     return static_cast<ffrt_queue_t>(handler);
315 }
316 
317 API_ATTRIBUTE((visibility("default")))
ffrt_queue_dump(ffrt_queue_t queue,const char * tag,char * buf,uint32_t len,bool history_info)318 int ffrt_queue_dump(ffrt_queue_t queue, const char* tag, char* buf, uint32_t len, bool history_info)
319 {
320     FFRT_COND_DO_ERR((queue == nullptr), return -1, "input invalid, queue is nullptr");
321     FFRT_COND_DO_ERR((tag == nullptr || buf == nullptr), return -1, "input invalid, tag or buf is nullptr");
322     QueueHandler* handler = static_cast<QueueHandler*>(queue);
323     return handler->Dump(tag, buf, len, history_info);
324 }
325 
326 API_ATTRIBUTE((visibility("default")))
ffrt_queue_size_dump(ffrt_queue_t queue,ffrt_inner_queue_priority_t priority)327 int ffrt_queue_size_dump(ffrt_queue_t queue, ffrt_inner_queue_priority_t priority)
328 {
329     if (priority > ffrt_inner_queue_priority_idle || priority < ffrt_inner_queue_priority_vip) {
330         FFRT_LOGE("priority:%d is not valid", priority);
331         return -1;
332     }
333     FFRT_COND_DO_ERR((queue == nullptr), return -1, "input invalid, queue is nullptr");
334     QueueHandler* handler = static_cast<QueueHandler*>(queue);
335     return handler->DumpSize(priority);
336 }