• 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 #include <memory>
17 #include <vector>
18 
19 #include "ffrt_inner.h"
20 #include "internal_inc/osal.h"
21 #ifdef USE_OHOS_QOS
22 #include "qos.h"
23 #else
24 #include "staging_qos/sched/qos.h"
25 #endif
26 #include "sched/task_scheduler.h"
27 #include "core/task_attr_private.h"
28 #include "internal_inc/config.h"
29 #include "eu/osattr_manager.h"
30 #include "eu/cpu_worker.h"
31 #include "dfx/log/ffrt_log_api.h"
32 #include "dfx/trace_record/ffrt_trace_record.h"
33 #include "dfx/watchdog/watchdog_util.h"
34 #include "eu/func_manager.h"
35 #include "util/ffrt_facade.h"
36 #include "util/slab.h"
37 #include "eu/sexecute_unit.h"
38 #include "core/task_io.h"
39 #include "core/task_wrapper.h"
40 #include "sync/poller.h"
41 #include "util/spmc_queue.h"
42 #include "tm/task_factory.h"
43 #include "tm/queue_task.h"
44 #include "util/common_const.h"
45 #include "util/ref_function_header.h"
46 
47 constexpr uint64_t MAX_DELAY_US_COUNT = 1000000ULL * 100 * 60 * 60 * 24 * 365; // 100 year
48 constexpr uint64_t MAX_TIMEOUT_US_COUNT = 1000000ULL * 100 * 60 * 60 * 24 * 365; // 100 year
49 
50 namespace ffrt {
submit_impl(bool has_handle,ffrt_task_handle_t & handle,ffrt_function_header_t * f,const ffrt_deps_t * ins,const ffrt_deps_t * outs,const task_attr_private * attr)51 inline void submit_impl(bool has_handle, ffrt_task_handle_t &handle, ffrt_function_header_t *f,
52     const ffrt_deps_t *ins, const ffrt_deps_t *outs, const task_attr_private *attr)
53 {
54     FFRTFacade::GetDMInstance().onSubmit(has_handle, handle, f, ins, outs, attr);
55 }
56 
DestroyFunctionWrapper(ffrt_function_header_t * f,ffrt_function_kind_t kind=ffrt_function_kind_general)57 void DestroyFunctionWrapper(ffrt_function_header_t* f,
58     ffrt_function_kind_t kind = ffrt_function_kind_general)
59 {
60     if (f == nullptr || f->destroy == nullptr) {
61         return;
62     }
63     f->destroy(f);
64     // 按照kind转化为对应类型,释放内存
65     if (kind == ffrt_function_kind_general) {
66         CPUEUTask *t = reinterpret_cast<CPUEUTask *>(static_cast<uintptr_t>(
67             static_cast<size_t>(reinterpret_cast<uintptr_t>(f)) - OFFSETOF(CPUEUTask, func_storage)));
68         TaskFactory<CPUEUTask>::Free_(t);
69         return;
70     }
71     QueueTask *t = reinterpret_cast<QueueTask *>(static_cast<uintptr_t>(
72         static_cast<size_t>(reinterpret_cast<uintptr_t>(f)) - OFFSETOF(QueueTask, func_storage)));
73     TaskFactory<QueueTask>::Free_(t);
74 }
75 
76 API_ATTRIBUTE((visibility("default")))
sync_io(int fd)77 void sync_io(int fd)
78 {
79     FFRTFacade::GetPPInstance().WaitFdEvent(fd);
80 }
81 
82 API_ATTRIBUTE((visibility("default")))
set_trace_tag(const char * name)83 void set_trace_tag(const char* name)
84 {
85     // !deprecated
86     (void)name;
87 }
88 
89 API_ATTRIBUTE((visibility("default")))
clear_trace_tag()90 void clear_trace_tag()
91 {
92     // !deprecated
93 }
94 
CreateDelayDeps(ffrt_task_handle_t & handle,const ffrt_deps_t * in_deps,const ffrt_deps_t * out_deps,task_attr_private * p)95 void CreateDelayDeps(
96     ffrt_task_handle_t &handle, const ffrt_deps_t *in_deps, const ffrt_deps_t *out_deps, task_attr_private *p)
97 {
98     // setting dependences is not supportted for delayed task
99     if (unlikely(((in_deps != nullptr) && (in_deps->len != 0)) || ((out_deps != nullptr) && (out_deps->len != 0)))) {
100         FFRT_LOGE("delayed task do not support dependence, in_deps/out_deps ignored.");
101     }
102 
103     // delay task
104     uint64_t delayUs = p->delay_;
105     std::function<void()> &&func = [delayUs]() {
106         this_task::sleep_for(std::chrono::microseconds(delayUs));
107         FFRT_LOGD("submit task delay time [%d us] has ended.", delayUs);
108     };
109     ffrt_function_header_t *delay_func = create_function_wrapper(std::move(func));
110     submit_impl(true, handle, delay_func, nullptr, nullptr, reinterpret_cast<task_attr_private *>(p));
111 }
112 } // namespace ffrt
113 
114 #ifdef __cplusplus
115 extern "C" {
116 #endif
117 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_init(ffrt_task_attr_t * attr)118 int ffrt_task_attr_init(ffrt_task_attr_t *attr)
119 {
120     if (unlikely(!attr)) {
121         FFRT_LOGE("attr should be a valid address");
122         return -1;
123     }
124     static_assert(sizeof(ffrt::task_attr_private) <= ffrt_task_attr_storage_size,
125         "size must be less than ffrt_task_attr_storage_size");
126 
127     new (attr)ffrt::task_attr_private();
128     return 0;
129 }
130 
131 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_destroy(ffrt_task_attr_t * attr)132 void ffrt_task_attr_destroy(ffrt_task_attr_t *attr)
133 {
134     if (unlikely(!attr)) {
135         FFRT_LOGE("attr should be a valid address");
136         return;
137     }
138     auto p = reinterpret_cast<ffrt::task_attr_private *>(attr);
139     p->~task_attr_private();
140 }
141 
142 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_name(ffrt_task_attr_t * attr,const char * name)143 void ffrt_task_attr_set_name(ffrt_task_attr_t *attr, const char *name)
144 {
145     if (unlikely(!attr || !name)) {
146         FFRT_LOGE("invalid attr or name");
147         return;
148     }
149     (reinterpret_cast<ffrt::task_attr_private *>(attr))->name_ = name;
150 }
151 
152 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_get_name(const ffrt_task_attr_t * attr)153 const char *ffrt_task_attr_get_name(const ffrt_task_attr_t *attr)
154 {
155     if (unlikely(!attr)) {
156         FFRT_LOGE("attr should be a valid address");
157         return nullptr;
158     }
159     ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
160     return (reinterpret_cast<ffrt::task_attr_private *>(p))->name_.c_str();
161 }
162 
163 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_qos(ffrt_task_attr_t * attr,ffrt_qos_t qos)164 void ffrt_task_attr_set_qos(ffrt_task_attr_t *attr, ffrt_qos_t qos)
165 {
166     if (unlikely(!attr)) {
167         FFRT_LOGE("attr should be a valid address");
168         return;
169     }
170     if (ffrt::GetFuncQosMap() == nullptr) {
171         FFRT_LOGE("FuncQosMap has not regist");
172         return;
173     }
174     (reinterpret_cast<ffrt::task_attr_private *>(attr))->qos_ = ffrt::GetFuncQosMap()(qos);
175 }
176 
177 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_get_qos(const ffrt_task_attr_t * attr)178 ffrt_qos_t ffrt_task_attr_get_qos(const ffrt_task_attr_t *attr)
179 {
180     if (unlikely(!attr)) {
181         FFRT_LOGE("attr should be a valid address");
182         return static_cast<int>(ffrt_qos_default);
183     }
184     ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
185     return (reinterpret_cast<ffrt::task_attr_private *>(p))->qos_;
186 }
187 
188 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_delay(ffrt_task_attr_t * attr,uint64_t delay_us)189 void ffrt_task_attr_set_delay(ffrt_task_attr_t *attr, uint64_t delay_us)
190 {
191     if (unlikely(!attr)) {
192         FFRT_LOGE("attr should be a valid address");
193         return;
194     }
195 
196     if (delay_us > MAX_DELAY_US_COUNT) {
197         FFRT_LOGW("delay_us exceeds maximum allowed value %llu us. Clamping to %llu us.", delay_us, MAX_DELAY_US_COUNT);
198         delay_us = MAX_DELAY_US_COUNT;
199     }
200 
201     (reinterpret_cast<ffrt::task_attr_private *>(attr))->delay_ = delay_us;
202 }
203 
204 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_get_delay(const ffrt_task_attr_t * attr)205 uint64_t ffrt_task_attr_get_delay(const ffrt_task_attr_t *attr)
206 {
207     if (unlikely(!attr)) {
208         FFRT_LOGE("attr should be a valid address");
209         return 0;
210     }
211     ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
212     return (reinterpret_cast<ffrt::task_attr_private *>(p))->delay_;
213 }
214 
215 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_timeout(ffrt_task_attr_t * attr,uint64_t timeout_us)216 void ffrt_task_attr_set_timeout(ffrt_task_attr_t *attr, uint64_t timeout_us)
217 {
218     if (unlikely(!attr)) {
219         FFRT_LOGE("attr should be a valid address");
220         return;
221     }
222     if (timeout_us < ONE_THOUSAND) {
223         (reinterpret_cast<ffrt::task_attr_private *>(attr))->timeout_ = ONE_THOUSAND;
224         return;
225     }
226 
227     if (timeout_us > MAX_TIMEOUT_US_COUNT) {
228         FFRT_LOGW("timeout_us exceeds maximum allowed value %llu us. Clamping to %llu us.", timeout_us,
229             MAX_TIMEOUT_US_COUNT);
230         timeout_us = MAX_TIMEOUT_US_COUNT;
231     }
232 
233     (reinterpret_cast<ffrt::task_attr_private *>(attr))->timeout_ = timeout_us;
234 }
235 
236 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_get_timeout(const ffrt_task_attr_t * attr)237 uint64_t ffrt_task_attr_get_timeout(const ffrt_task_attr_t *attr)
238 {
239     if (unlikely(!attr)) {
240         FFRT_LOGE("attr should be a valid address");
241         return 0;
242     }
243     ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
244     return (reinterpret_cast<ffrt::task_attr_private *>(p))->timeout_;
245 }
246 
247 
248 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_notify_worker(ffrt_task_attr_t * attr,bool notify)249 void ffrt_task_attr_set_notify_worker(ffrt_task_attr_t* attr, bool notify)
250 {
251     if (unlikely(!attr)) {
252         FFRT_LOGE("attr should be a valid address");
253         return;
254     }
255     (reinterpret_cast<ffrt::task_attr_private *>(attr))->notifyWorker_ = notify;
256 }
257 
258 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_queue_priority(ffrt_task_attr_t * attr,ffrt_queue_priority_t priority)259 void ffrt_task_attr_set_queue_priority(ffrt_task_attr_t* attr, ffrt_queue_priority_t priority)
260 {
261     if (unlikely(!attr)) {
262         FFRT_LOGE("attr should be a valid address");
263         return;
264     }
265 
266     // eventhandler inner priority is one more than the kits priority
267     int prio = static_cast<int>(priority);
268     if (prio < static_cast<int>(ffrt_queue_priority_immediate) ||
269         prio > static_cast<int>(ffrt_queue_priority_idle) + 1) {
270         FFRT_LOGE("priority should be a valid priority");
271         return;
272     }
273 
274     (reinterpret_cast<ffrt::task_attr_private *>(attr))->prio_ = priority;
275 }
276 
277 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_get_queue_priority(const ffrt_task_attr_t * attr)278 ffrt_queue_priority_t ffrt_task_attr_get_queue_priority(const ffrt_task_attr_t* attr)
279 {
280     if (unlikely(!attr)) {
281         FFRT_LOGE("attr should be a valid address");
282         return ffrt_queue_priority_immediate;
283     }
284     ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
285     return static_cast<ffrt_queue_priority_t>((reinterpret_cast<ffrt::task_attr_private *>(p))->prio_);
286 }
287 
288 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_stack_size(ffrt_task_attr_t * attr,uint64_t size)289 void ffrt_task_attr_set_stack_size(ffrt_task_attr_t* attr, uint64_t size)
290 {
291     if (unlikely(!attr)) {
292         FFRT_LOGE("attr should be a valid address");
293         return;
294     }
295     (reinterpret_cast<ffrt::task_attr_private *>(attr))->stackSize_ = size;
296 }
297 
298 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_get_stack_size(const ffrt_task_attr_t * attr)299 uint64_t ffrt_task_attr_get_stack_size(const ffrt_task_attr_t* attr)
300 {
301     if (unlikely(!attr)) {
302         FFRT_LOGE("attr should be a valid address");
303         return 0;
304     }
305     return (reinterpret_cast<const ffrt::task_attr_private *>(attr))->stackSize_;
306 }
307 
308 // submit
309 API_ATTRIBUTE((visibility("default")))
ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind)310 void *ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind)
311 {
312     if (kind == ffrt_function_kind_general) {
313         return ffrt::TaskFactory<ffrt::CPUEUTask>::Alloc()->func_storage;
314     }
315     return ffrt::TaskFactory<ffrt::QueueTask>::Alloc()->func_storage;
316 }
317 
318 API_ATTRIBUTE((visibility("default")))
ffrt_submit_base(ffrt_function_header_t * f,const ffrt_deps_t * in_deps,const ffrt_deps_t * out_deps,const ffrt_task_attr_t * attr)319 void ffrt_submit_base(ffrt_function_header_t *f, const ffrt_deps_t *in_deps, const ffrt_deps_t *out_deps,
320     const ffrt_task_attr_t *attr)
321 {
322     if (unlikely(!f)) {
323         FFRT_LOGE("function handler should not be empty");
324         return;
325     }
326     ffrt_task_handle_t handle;
327     ffrt::task_attr_private *p = reinterpret_cast<ffrt::task_attr_private *>(const_cast<ffrt_task_attr_t *>(attr));
328     if (likely(attr == nullptr || ffrt_task_attr_get_delay(attr) == 0)) {
329         ffrt::submit_impl(false, handle, f, in_deps, out_deps, p);
330         return;
331     }
332 
333     // task after delay
334     ffrt_task_handle_t delay_handle;
335     uint64_t timeout = p->timeout_;
336     p->timeout_ = 0;
337     p->isDelaying_ = true;
338     ffrt::CreateDelayDeps(delay_handle, in_deps, out_deps, p);
339     p->isDelaying_ = false;
340     p->timeout_ = timeout;
341     std::vector<ffrt_dependence_t> deps = {{ffrt_dependence_task, delay_handle}};
342     ffrt_deps_t delay_deps {static_cast<uint32_t>(deps.size()), deps.data()};
343     ffrt::submit_impl(false, handle, f, &delay_deps, nullptr, p);
344     ffrt_task_handle_destroy(delay_handle);
345 }
346 
347 API_ATTRIBUTE((visibility("default")))
ffrt_submit_f(ffrt_function_t func,void * arg,const ffrt_deps_t * in_deps,const ffrt_deps_t * out_deps,const ffrt_task_attr_t * attr)348 void ffrt_submit_f(ffrt_function_t func, void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps,
349     const ffrt_task_attr_t* attr)
350 {
351     ffrt_function_header_t* f = ffrt_create_function_wrapper(func, nullptr, arg, ffrt_function_kind_general);
352     ffrt_submit_base(f, in_deps, out_deps, attr);
353 }
354 
355 API_ATTRIBUTE((visibility("default")))
ffrt_submit_h_base(ffrt_function_header_t * f,const ffrt_deps_t * in_deps,const ffrt_deps_t * out_deps,const ffrt_task_attr_t * attr)356 ffrt_task_handle_t ffrt_submit_h_base(ffrt_function_header_t *f, const ffrt_deps_t *in_deps,
357     const ffrt_deps_t *out_deps, const ffrt_task_attr_t *attr)
358 {
359     if (unlikely(!f)) {
360         FFRT_LOGE("function handler should not be empty");
361         return nullptr;
362     }
363     ffrt_task_handle_t handle = nullptr;
364     ffrt::task_attr_private *p = reinterpret_cast<ffrt::task_attr_private *>(const_cast<ffrt_task_attr_t *>(attr));
365     if (likely(attr == nullptr || ffrt_task_attr_get_delay(attr) == 0)) {
366         ffrt::submit_impl(true, handle, f, in_deps, out_deps, p);
367         return handle;
368     }
369 
370     // task after delay
371     ffrt_task_handle_t delay_handle = nullptr;
372     uint64_t timeout = p->timeout_;
373     p->timeout_ = 0;
374     ffrt::CreateDelayDeps(delay_handle, in_deps, out_deps, p);
375     p->timeout_ = timeout;
376     std::vector<ffrt_dependence_t> deps = {{ffrt_dependence_task, delay_handle}};
377     ffrt_deps_t delay_deps {static_cast<uint32_t>(deps.size()), deps.data()};
378     ffrt::submit_impl(true, handle, f, &delay_deps, nullptr, p);
379     ffrt_task_handle_destroy(delay_handle);
380     return handle;
381 }
382 
383 API_ATTRIBUTE((visibility("default")))
ffrt_submit_h_f(ffrt_function_t func,void * arg,const ffrt_deps_t * in_deps,const ffrt_deps_t * out_deps,const ffrt_task_attr_t * attr)384 ffrt_task_handle_t ffrt_submit_h_f(ffrt_function_t func, void* arg, const ffrt_deps_t* in_deps,
385     const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
386 {
387     ffrt_function_header_t* f = ffrt_create_function_wrapper(func, nullptr, arg, ffrt_function_kind_general);
388     return ffrt_submit_h_base(f, in_deps, out_deps, attr);
389 }
390 
391 API_ATTRIBUTE((visibility("default")))
ffrt_task_handle_inc_ref(ffrt_task_handle_t handle)392 uint32_t ffrt_task_handle_inc_ref(ffrt_task_handle_t handle)
393 {
394     if (handle == nullptr) {
395         FFRT_LOGE("input task handle is invalid");
396         return -1;
397     }
398     return static_cast<ffrt::CPUEUTask*>(handle)->IncDeleteRef();
399 }
400 
401 API_ATTRIBUTE((visibility("default")))
ffrt_task_handle_dec_ref(ffrt_task_handle_t handle)402 uint32_t ffrt_task_handle_dec_ref(ffrt_task_handle_t handle)
403 {
404     if (handle == nullptr) {
405         FFRT_LOGE("input task handle is invalid");
406         return -1;
407     }
408     return static_cast<ffrt::CPUEUTask*>(handle)->DecDeleteRef();
409 }
410 
411 API_ATTRIBUTE((visibility("default")))
ffrt_task_handle_destroy(ffrt_task_handle_t handle)412 void ffrt_task_handle_destroy(ffrt_task_handle_t handle)
413 {
414     ffrt_task_handle_dec_ref(handle);
415 }
416 
417 API_ATTRIBUTE((visibility("default")))
ffrt_task_handle_get_id(ffrt_task_handle_t handle)418 uint64_t ffrt_task_handle_get_id(ffrt_task_handle_t handle)
419 {
420     FFRT_COND_DO_ERR((handle == nullptr), return 0, "input task handle is invalid");
421     return static_cast<ffrt::TaskBase*>(handle)->gid;
422 }
423 
424 // wait
425 API_ATTRIBUTE((visibility("default")))
ffrt_wait_deps(const ffrt_deps_t * deps)426 void ffrt_wait_deps(const ffrt_deps_t *deps)
427 {
428     if (unlikely(!deps)) {
429         FFRT_LOGE("deps should not be empty");
430         return;
431     }
432     std::vector<ffrt_dependence_t> v(deps->len);
433     for (uint64_t i = 0; i < deps->len; ++i) {
434         v[i] = deps->items[i];
435     }
436     ffrt_deps_t d = { deps->len, v.data() };
437     ffrt::FFRTFacade::GetDMInstance().onWait(&d);
438 }
439 
440 API_ATTRIBUTE((visibility("default")))
ffrt_wait()441 void ffrt_wait()
442 {
443     ffrt::FFRTFacade::GetDMInstance().onWait();
444 }
445 
446 API_ATTRIBUTE((visibility("default")))
ffrt_set_cgroup_attr(ffrt_qos_t qos,ffrt_os_sched_attr * attr)447 int ffrt_set_cgroup_attr(ffrt_qos_t qos, ffrt_os_sched_attr *attr)
448 {
449     if (unlikely(!attr)) {
450         FFRT_LOGE("attr should not be empty");
451         return -1;
452     }
453     if (ffrt::GetFuncQosMap() == nullptr) {
454         FFRT_LOGE("FuncQosMap has not regist");
455         return -1;
456     }
457     ffrt::QoS _qos = ffrt::GetFuncQosMap()(qos);
458     return ffrt::OSAttrManager::Instance()->UpdateSchedAttr(_qos, attr);
459 }
460 
461 API_ATTRIBUTE((visibility("default")))
ffrt_restore_qos_config()462 void ffrt_restore_qos_config()
463 {
464     ffrt::FFRTFacade::GetEUInstance().RestoreThreadConfig();
465 }
466 
467 API_ATTRIBUTE((visibility("default")))
ffrt_set_cpu_worker_max_num(ffrt_qos_t qos,uint32_t num)468 int ffrt_set_cpu_worker_max_num(ffrt_qos_t qos, uint32_t num)
469 {
470     if (num == 0 || num > ffrt::QOS_WORKER_MAXNUM) {
471         FFRT_LOGE("qos[%d] worker num[%u] is invalid.", qos, num);
472         return -1;
473     }
474     if (ffrt::GetFuncQosMap() == nullptr) {
475         FFRT_LOGE("FuncQosMap has not regist");
476         return -1;
477     }
478     ffrt::QoS _qos = ffrt::GetFuncQosMap()(qos);
479     if (((qos != ffrt::qos_default) && (_qos() == ffrt::qos_default)) || (qos <= ffrt::qos_inherit)) {
480         FFRT_LOGE("qos[%d] is invalid.", qos);
481         return -1;
482     }
483     return ffrt::FFRTFacade::GetEUInstance().SetWorkerMaxNum(_qos, num);
484 }
485 
486 API_ATTRIBUTE((visibility("default")))
ffrt_notify_workers(ffrt_qos_t qos,int number)487 void ffrt_notify_workers(ffrt_qos_t qos, int number)
488 {
489     if (qos < ffrt::QoS::Min() || qos >= ffrt::QoS::Max() || number <= 0) {
490         FFRT_LOGE("qos [%d] or number [%d] or is invalid.", qos, number);
491         return;
492     }
493 
494     ffrt::FFRTFacade::GetEUInstance().NotifyWorkers(qos, number);
495 }
496 
497 API_ATTRIBUTE((visibility("default")))
ffrt_set_worker_stack_size(ffrt_qos_t qos,size_t stack_size)498 ffrt_error_t ffrt_set_worker_stack_size(ffrt_qos_t qos, size_t stack_size)
499 {
500     if (qos < ffrt::QoS::Min() || qos >= ffrt::QoS::Max() || stack_size < PTHREAD_STACK_MIN) {
501         FFRT_LOGE("qos [%d] or stack size [%d] is invalid.", qos, stack_size);
502         return ffrt_error_inval;
503     }
504 
505     if (ffrt::FFRTFacade::GetEUInstance().SetWorkerStackSize(ffrt::QoS(qos), stack_size) != 0) {
506         return ffrt_error;
507     }
508 
509     return ffrt_success;
510 }
511 
512 API_ATTRIBUTE((visibility("default")))
ffrt_this_task_update_qos(ffrt_qos_t qos)513 int ffrt_this_task_update_qos(ffrt_qos_t qos)
514 {
515     if (ffrt::GetFuncQosMap() == nullptr) {
516         FFRT_LOGE("FuncQosMap has not regist");
517         return 1;
518     }
519     ffrt::QoS _qos = ffrt::GetFuncQosMap()(qos);
520     auto curTask = ffrt::ExecuteCtx::Cur()->task;
521     if (curTask == nullptr) {
522         FFRT_SYSEVENT_LOGW("task is nullptr");
523         return 1;
524     }
525 
526     FFRT_COND_DO_ERR((curTask->type != ffrt_normal_task), return 1, "update qos task type invalid");
527     if (_qos() == curTask->qos_) {
528         FFRT_LOGW("the target qos is equal to current qos, no need update");
529         return 0;
530     }
531 
532     curTask->SetQos(_qos);
533     ffrt_yield();
534 
535     return 0;
536 }
537 
538 API_ATTRIBUTE((visibility("default")))
ffrt_this_task_get_qos(void)539 ffrt_qos_t ffrt_this_task_get_qos(void)
540 {
541     if (ffrt::ExecuteCtx::Cur()->task == nullptr) {
542         FFRT_LOGW("task is nullptr");
543         return static_cast<int>(ffrt_qos_default);
544     }
545     return ffrt::ExecuteCtx::Cur()->qos();
546 }
547 
548 API_ATTRIBUTE((visibility("default")))
ffrt_this_task_get_id()549 uint64_t ffrt_this_task_get_id()
550 {
551     auto curTask = ffrt::ExecuteCtx::Cur()->task;
552     if (curTask == nullptr) {
553         return 0;
554     }
555 
556     if (curTask->type == ffrt_normal_task) {
557         return curTask->gid;
558     } else if (curTask->type == ffrt_queue_task) {
559         return reinterpret_cast<ffrt::QueueTask*>(curTask)->GetHandler()->GetExecTaskId();
560     }
561 
562     return 0;
563 }
564 
565 API_ATTRIBUTE((visibility("default")))
ffrt_this_queue_get_id()566 int64_t ffrt_this_queue_get_id()
567 {
568     auto curTask = ffrt::ExecuteCtx::Cur()->task;
569     if (curTask == nullptr || curTask->type != ffrt_queue_task) {
570         // not serial queue task
571         return -1;
572     }
573 
574     ffrt::QueueTask* task = static_cast<ffrt::QueueTask*>(curTask);
575     return task->GetQueueId();
576 }
577 
578 API_ATTRIBUTE((visibility("default")))
ffrt_skip(ffrt_task_handle_t handle)579 int ffrt_skip(ffrt_task_handle_t handle)
580 {
581     FFRT_COND_DO_ERR((handle == nullptr), return ffrt_error_inval, "input ffrt task handle is invalid.");
582     return ffrt::FFRTFacade::GetDMInstance().onSkip(handle);
583 }
584 
585 API_ATTRIBUTE((visibility("default")))
ffrt_executor_task_submit(ffrt_executor_task_t * task,const ffrt_task_attr_t * attr)586 void ffrt_executor_task_submit(ffrt_executor_task_t* task, const ffrt_task_attr_t* attr)
587 {
588     if (task == nullptr) {
589         FFRT_LOGE("function handler should not be empty");
590         return;
591     }
592     ffrt::task_attr_private* p = reinterpret_cast<ffrt::task_attr_private *>(const_cast<ffrt_task_attr_t *>(attr));
593     if (likely(attr == nullptr || ffrt_task_attr_get_delay(attr) == 0)) {
594         ffrt::FFRTFacade::GetDMInstance().onSubmitUV(task, p);
595         return;
596     }
597     FFRT_LOGE("uv function does not support delay");
598 }
599 
600 API_ATTRIBUTE((visibility("default")))
ffrt_executor_task_register_func(ffrt_executor_task_func func,ffrt_executor_task_type_t type)601 void ffrt_executor_task_register_func(ffrt_executor_task_func func, ffrt_executor_task_type_t type)
602 {
603     FFRT_COND_DO_ERR((func == nullptr), return, "function handler should not be empty.");
604     ffrt::FuncManager* func_mg = ffrt::FuncManager::Instance();
605     func_mg->insert(type, func);
606 }
607 
608 API_ATTRIBUTE((visibility("default")))
ffrt_executor_task_cancel(ffrt_executor_task_t * task,const ffrt_qos_t qos)609 int ffrt_executor_task_cancel(ffrt_executor_task_t* task, const ffrt_qos_t qos)
610 {
611     FFRT_COND_DO_ERR((qos == ffrt::qos_inherit), return 0, "Level incorrect");
612     FFRT_COND_DO_ERR((task == nullptr), return 0, "libuv task is NULL");
613 
614     ffrt::Scheduler* sch = ffrt::FFRTFacade::GetSchedInstance();
615     bool ret = sch->CancelUVWork(task, qos);
616     if (ret) {
617         ffrt::FFRTTraceRecord::TaskCancel<ffrt_uv_task>(qos);
618     }
619     return static_cast<int>(ret);
620 }
621 
622 API_ATTRIBUTE((visibility("default")))
ffrt_get_cur_task(void)623 void* ffrt_get_cur_task(void)
624 {
625     if (ffrt::IsCoTask(ffrt::ExecuteCtx::Cur()->task)) {
626         return ffrt::ExecuteCtx::Cur()->task;
627     }
628     return nullptr;
629 }
630 
631 API_ATTRIBUTE((visibility("default")))
ffrt_get_current_coroutine_stack(void ** stack_addr,size_t * size)632 bool ffrt_get_current_coroutine_stack(void** stack_addr, size_t* size)
633 {
634     if (stack_addr == nullptr || size == nullptr) {
635         return false;
636     }
637 
638     if (!ffrt::USE_COROUTINE) {
639         return false;
640     }
641 
642     // init is false to avoid the crash issue caused by nested calls to malloc during initialization.
643     auto ctx = ffrt::ExecuteCtx::Cur(false);
644     if (ctx == nullptr) {
645         return false;
646     }
647 
648     auto curTask = ffrt::ExecuteCtx::Cur()->task;
649     if (IsCoTask(curTask)) {
650         auto co = static_cast<ffrt::CoTask*>(curTask)->coRoutine;
651         if (co) {
652             *size = co->stkMem.size;
653             *stack_addr = GetCoStackAddr(co);
654             return true;
655         }
656     }
657     return false;
658 }
659 
660 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_set_local(ffrt_task_attr_t * attr,bool task_local)661 void ffrt_task_attr_set_local(ffrt_task_attr_t* attr, bool task_local)
662 {
663     if (unlikely(!attr)) {
664         FFRT_LOGE("attr should be a valid address");
665         return;
666     }
667     (reinterpret_cast<ffrt::task_attr_private *>(attr))->taskLocal_ = task_local;
668 }
669 
670 API_ATTRIBUTE((visibility("default")))
ffrt_task_attr_get_local(ffrt_task_attr_t * attr)671 bool ffrt_task_attr_get_local(ffrt_task_attr_t* attr)
672 {
673     if (unlikely(!attr)) {
674         FFRT_LOGE("attr should be a valid address");
675         return false;
676     }
677     return (reinterpret_cast<ffrt::task_attr_private *>(attr))->taskLocal_;
678 }
679 
680 API_ATTRIBUTE((visibility("default")))
ffrt_task_get_tid(void * task_handle)681 pthread_t ffrt_task_get_tid(void* task_handle)
682 {
683     if (task_handle == nullptr) {
684         FFRT_LOGE("invalid task handle");
685         return 0;
686     }
687 
688     auto task = reinterpret_cast<ffrt::CPUEUTask*>(task_handle);
689     return task->runningTid.load();
690 }
691 
692 API_ATTRIBUTE((visibility("default")))
ffrt_get_cur_cached_task_id(void)693 uint64_t ffrt_get_cur_cached_task_id(void)
694 {
695     uint64_t gid = ffrt_this_task_get_id();
696     if (gid == 0) {
697         return ffrt::ExecuteCtx::Cur()->lastGid_;
698     }
699 
700     return gid;
701 }
702 
703 API_ATTRIBUTE((visibility("default")))
ffrt_enable_worker_escape(uint64_t one_stage_interval_ms,uint64_t two_stage_interval_ms,uint64_t three_stage_interval_ms,uint64_t one_stage_worker_num,uint64_t two_stage_worker_num)704 int ffrt_enable_worker_escape(uint64_t one_stage_interval_ms, uint64_t two_stage_interval_ms,
705     uint64_t three_stage_interval_ms, uint64_t one_stage_worker_num, uint64_t two_stage_worker_num)
706 {
707     return ffrt::FFRTFacade::GetEUInstance().SetEscapeEnable(one_stage_interval_ms, two_stage_interval_ms,
708         three_stage_interval_ms, one_stage_worker_num, two_stage_worker_num);
709 }
710 
711 API_ATTRIBUTE((visibility("default")))
ffrt_disable_worker_escape(void)712 void ffrt_disable_worker_escape(void)
713 {
714     ffrt::FFRTFacade::GetEUInstance().SetEscapeDisable();
715 }
716 
717 API_ATTRIBUTE((visibility("default")))
ffrt_set_sched_mode(ffrt_qos_t qos,ffrt_sched_mode mode)718 void ffrt_set_sched_mode(ffrt_qos_t qos, ffrt_sched_mode mode)
719 {
720     if (qos < ffrt::QoS::Min() || qos >= ffrt::QoS::Max()) {
721         FFRT_LOGE("Currently, the energy saving mode is unavailable or qos [%d] is invalid..", qos);
722         return;
723     }
724     ffrt::FFRTFacade::GetEUInstance().SetSchedMode(ffrt::QoS(qos), static_cast<ffrt::sched_mode_type>(mode));
725 }
726 #ifdef __cplusplus
727 }
728 #endif
729