1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#include <memory>
17484543d1Sopenharmony_ci#include <vector>
18484543d1Sopenharmony_ci
19484543d1Sopenharmony_ci#include "ffrt_inner.h"
20484543d1Sopenharmony_ci#include "internal_inc/osal.h"
21484543d1Sopenharmony_ci#include "sync/io_poller.h"
22484543d1Sopenharmony_ci#include "qos.h"
23484543d1Sopenharmony_ci#include "sched/task_scheduler.h"
24484543d1Sopenharmony_ci#include "task_attr_private.h"
25484543d1Sopenharmony_ci#include "internal_inc/config.h"
26484543d1Sopenharmony_ci#include "eu/osattr_manager.h"
27484543d1Sopenharmony_ci#include "eu/worker_thread.h"
28484543d1Sopenharmony_ci#include "eu/cpu_monitor.h"
29484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h"
30484543d1Sopenharmony_ci#include "dfx/trace_record/ffrt_trace_record.h"
31484543d1Sopenharmony_ci#include "dfx/watchdog/watchdog_util.h"
32484543d1Sopenharmony_ci#include "eu/func_manager.h"
33484543d1Sopenharmony_ci#include "util/ffrt_facade.h"
34484543d1Sopenharmony_ci#include "util/slab.h"
35484543d1Sopenharmony_ci#include "eu/sexecute_unit.h"
36484543d1Sopenharmony_ci#include "core/task_io.h"
37484543d1Sopenharmony_ci#include "sync/poller.h"
38484543d1Sopenharmony_ci#include "util/spmc_queue.h"
39484543d1Sopenharmony_ci#include "tm/task_factory.h"
40484543d1Sopenharmony_ci#include "tm/queue_task.h"
41484543d1Sopenharmony_ci
42484543d1Sopenharmony_cinamespace ffrt {
43484543d1Sopenharmony_ciinline void submit_impl(bool has_handle, ffrt_task_handle_t &handle, ffrt_function_header_t *f,
44484543d1Sopenharmony_ci    const ffrt_deps_t *ins, const ffrt_deps_t *outs, const task_attr_private *attr)
45484543d1Sopenharmony_ci{
46484543d1Sopenharmony_ci    FFRTFacade::GetDMInstance().onSubmit(has_handle, handle, f, ins, outs, attr);
47484543d1Sopenharmony_ci}
48484543d1Sopenharmony_ci
49484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
50484543d1Sopenharmony_civoid sync_io(int fd)
51484543d1Sopenharmony_ci{
52484543d1Sopenharmony_ci    ffrt_wait_fd(fd);
53484543d1Sopenharmony_ci}
54484543d1Sopenharmony_ci
55484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
56484543d1Sopenharmony_civoid set_trace_tag(const char* name)
57484543d1Sopenharmony_ci{
58484543d1Sopenharmony_ci    CPUEUTask* curTask = ffrt::ExecuteCtx::Cur()->task;
59484543d1Sopenharmony_ci    if (curTask != nullptr) {
60484543d1Sopenharmony_ci        curTask->SetTraceTag(name);
61484543d1Sopenharmony_ci    }
62484543d1Sopenharmony_ci}
63484543d1Sopenharmony_ci
64484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
65484543d1Sopenharmony_civoid clear_trace_tag()
66484543d1Sopenharmony_ci{
67484543d1Sopenharmony_ci    CPUEUTask* curTask = ffrt::ExecuteCtx::Cur()->task;
68484543d1Sopenharmony_ci    if (curTask != nullptr) {
69484543d1Sopenharmony_ci        curTask->ClearTraceTag();
70484543d1Sopenharmony_ci    }
71484543d1Sopenharmony_ci}
72484543d1Sopenharmony_ci
73484543d1Sopenharmony_civoid CreateDelayDeps(
74484543d1Sopenharmony_ci    ffrt_task_handle_t &handle, const ffrt_deps_t *in_deps, const ffrt_deps_t *out_deps, task_attr_private *p)
75484543d1Sopenharmony_ci{
76484543d1Sopenharmony_ci    // setting dependences is not supportted for delayed task
77484543d1Sopenharmony_ci    if (unlikely(((in_deps != nullptr) && (in_deps->len != 0)) || ((out_deps != nullptr) && (out_deps->len != 0)))) {
78484543d1Sopenharmony_ci        FFRT_LOGE("delayed task do not support dependence, in_deps/out_deps ignored.");
79484543d1Sopenharmony_ci    }
80484543d1Sopenharmony_ci
81484543d1Sopenharmony_ci    // delay task
82484543d1Sopenharmony_ci    uint64_t delayUs = p->delay_;
83484543d1Sopenharmony_ci    std::function<void()> &&func = [delayUs]() {
84484543d1Sopenharmony_ci        this_task::sleep_for(std::chrono::microseconds(delayUs));
85484543d1Sopenharmony_ci        FFRT_LOGD("submit task delay time [%d us] has ended.", delayUs);
86484543d1Sopenharmony_ci    };
87484543d1Sopenharmony_ci    ffrt_function_header_t *delay_func = create_function_wrapper(std::move(func));
88484543d1Sopenharmony_ci    submit_impl(true, handle, delay_func, nullptr, nullptr, reinterpret_cast<task_attr_private *>(p));
89484543d1Sopenharmony_ci}
90484543d1Sopenharmony_ci} // namespace ffrt
91484543d1Sopenharmony_ci
92484543d1Sopenharmony_ci#ifdef __cplusplus
93484543d1Sopenharmony_ciextern "C" {
94484543d1Sopenharmony_ci#endif
95484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
96484543d1Sopenharmony_ciint ffrt_task_attr_init(ffrt_task_attr_t *attr)
97484543d1Sopenharmony_ci{
98484543d1Sopenharmony_ci    if (unlikely(!attr)) {
99484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
100484543d1Sopenharmony_ci        return -1;
101484543d1Sopenharmony_ci    }
102484543d1Sopenharmony_ci    static_assert(sizeof(ffrt::task_attr_private) <= ffrt_task_attr_storage_size,
103484543d1Sopenharmony_ci        "size must be less than ffrt_task_attr_storage_size");
104484543d1Sopenharmony_ci
105484543d1Sopenharmony_ci    new (attr)ffrt::task_attr_private();
106484543d1Sopenharmony_ci    return 0;
107484543d1Sopenharmony_ci}
108484543d1Sopenharmony_ci
109484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
110484543d1Sopenharmony_civoid ffrt_task_attr_destroy(ffrt_task_attr_t *attr)
111484543d1Sopenharmony_ci{
112484543d1Sopenharmony_ci    if (unlikely(!attr)) {
113484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
114484543d1Sopenharmony_ci        return;
115484543d1Sopenharmony_ci    }
116484543d1Sopenharmony_ci    auto p = reinterpret_cast<ffrt::task_attr_private *>(attr);
117484543d1Sopenharmony_ci    p->~task_attr_private();
118484543d1Sopenharmony_ci}
119484543d1Sopenharmony_ci
120484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
121484543d1Sopenharmony_civoid ffrt_task_attr_set_name(ffrt_task_attr_t *attr, const char *name)
122484543d1Sopenharmony_ci{
123484543d1Sopenharmony_ci    if (unlikely(!attr || !name)) {
124484543d1Sopenharmony_ci        FFRT_LOGE("invalid attr or name");
125484543d1Sopenharmony_ci        return;
126484543d1Sopenharmony_ci    }
127484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->name_ = name;
128484543d1Sopenharmony_ci}
129484543d1Sopenharmony_ci
130484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
131484543d1Sopenharmony_ciconst char *ffrt_task_attr_get_name(const ffrt_task_attr_t *attr)
132484543d1Sopenharmony_ci{
133484543d1Sopenharmony_ci    if (unlikely(!attr)) {
134484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
135484543d1Sopenharmony_ci        return nullptr;
136484543d1Sopenharmony_ci    }
137484543d1Sopenharmony_ci    ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
138484543d1Sopenharmony_ci    return (reinterpret_cast<ffrt::task_attr_private *>(p))->name_.c_str();
139484543d1Sopenharmony_ci}
140484543d1Sopenharmony_ci
141484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
142484543d1Sopenharmony_civoid ffrt_task_attr_set_qos(ffrt_task_attr_t *attr, ffrt_qos_t qos)
143484543d1Sopenharmony_ci{
144484543d1Sopenharmony_ci    if (unlikely(!attr)) {
145484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
146484543d1Sopenharmony_ci        return;
147484543d1Sopenharmony_ci    }
148484543d1Sopenharmony_ci    if (ffrt::GetFuncQosMap() == nullptr) {
149484543d1Sopenharmony_ci        FFRT_LOGE("FuncQosMap has not regist");
150484543d1Sopenharmony_ci        return;
151484543d1Sopenharmony_ci    }
152484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->qos_ = ffrt::GetFuncQosMap()(qos);
153484543d1Sopenharmony_ci}
154484543d1Sopenharmony_ci
155484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
156484543d1Sopenharmony_ciffrt_qos_t ffrt_task_attr_get_qos(const ffrt_task_attr_t *attr)
157484543d1Sopenharmony_ci{
158484543d1Sopenharmony_ci    if (unlikely(!attr)) {
159484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
160484543d1Sopenharmony_ci        return static_cast<int>(ffrt_qos_default);
161484543d1Sopenharmony_ci    }
162484543d1Sopenharmony_ci    ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
163484543d1Sopenharmony_ci    return (reinterpret_cast<ffrt::task_attr_private *>(p))->qos_;
164484543d1Sopenharmony_ci}
165484543d1Sopenharmony_ci
166484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
167484543d1Sopenharmony_civoid ffrt_task_attr_set_delay(ffrt_task_attr_t *attr, uint64_t delay_us)
168484543d1Sopenharmony_ci{
169484543d1Sopenharmony_ci    if (unlikely(!attr)) {
170484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
171484543d1Sopenharmony_ci        return;
172484543d1Sopenharmony_ci    }
173484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->delay_ = delay_us;
174484543d1Sopenharmony_ci}
175484543d1Sopenharmony_ci
176484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
177484543d1Sopenharmony_ciuint64_t ffrt_task_attr_get_delay(const ffrt_task_attr_t *attr)
178484543d1Sopenharmony_ci{
179484543d1Sopenharmony_ci    if (unlikely(!attr)) {
180484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
181484543d1Sopenharmony_ci        return 0;
182484543d1Sopenharmony_ci    }
183484543d1Sopenharmony_ci    ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
184484543d1Sopenharmony_ci    return (reinterpret_cast<ffrt::task_attr_private *>(p))->delay_;
185484543d1Sopenharmony_ci}
186484543d1Sopenharmony_ci
187484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
188484543d1Sopenharmony_civoid ffrt_task_attr_set_timeout(ffrt_task_attr_t *attr, uint64_t timeout_ms)
189484543d1Sopenharmony_ci{
190484543d1Sopenharmony_ci    if (unlikely(!attr)) {
191484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
192484543d1Sopenharmony_ci        return;
193484543d1Sopenharmony_ci    }
194484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->timeout_ = timeout_ms;
195484543d1Sopenharmony_ci}
196484543d1Sopenharmony_ci
197484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
198484543d1Sopenharmony_ciuint64_t ffrt_task_attr_get_timeout(const ffrt_task_attr_t *attr)
199484543d1Sopenharmony_ci{
200484543d1Sopenharmony_ci    if (unlikely(!attr)) {
201484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
202484543d1Sopenharmony_ci        return 0;
203484543d1Sopenharmony_ci    }
204484543d1Sopenharmony_ci    ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
205484543d1Sopenharmony_ci    return (reinterpret_cast<ffrt::task_attr_private *>(p))->timeout_;
206484543d1Sopenharmony_ci}
207484543d1Sopenharmony_ci
208484543d1Sopenharmony_ci
209484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
210484543d1Sopenharmony_civoid ffrt_task_attr_set_notify_worker(ffrt_task_attr_t* attr, bool notify)
211484543d1Sopenharmony_ci{
212484543d1Sopenharmony_ci    if (unlikely(!attr)) {
213484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
214484543d1Sopenharmony_ci        return;
215484543d1Sopenharmony_ci    }
216484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->notifyWorker_ = notify;
217484543d1Sopenharmony_ci}
218484543d1Sopenharmony_ci
219484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
220484543d1Sopenharmony_civoid ffrt_task_attr_set_queue_priority(ffrt_task_attr_t* attr, ffrt_queue_priority_t priority)
221484543d1Sopenharmony_ci{
222484543d1Sopenharmony_ci    if (unlikely(!attr)) {
223484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
224484543d1Sopenharmony_ci        return;
225484543d1Sopenharmony_ci    }
226484543d1Sopenharmony_ci
227484543d1Sopenharmony_ci    // eventhandler inner priority is one more than the kits priority
228484543d1Sopenharmony_ci    int prio = static_cast<int>(priority);
229484543d1Sopenharmony_ci    if (prio < static_cast<int>(ffrt_queue_priority_immediate) ||
230484543d1Sopenharmony_ci        prio > static_cast<int>(ffrt_queue_priority_idle) + 1) {
231484543d1Sopenharmony_ci        FFRT_LOGE("priority should be a valid priority");
232484543d1Sopenharmony_ci        return;
233484543d1Sopenharmony_ci    }
234484543d1Sopenharmony_ci
235484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->prio_ = priority;
236484543d1Sopenharmony_ci}
237484543d1Sopenharmony_ci
238484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
239484543d1Sopenharmony_ciffrt_queue_priority_t ffrt_task_attr_get_queue_priority(const ffrt_task_attr_t* attr)
240484543d1Sopenharmony_ci{
241484543d1Sopenharmony_ci    if (unlikely(!attr)) {
242484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
243484543d1Sopenharmony_ci        return ffrt_queue_priority_immediate;
244484543d1Sopenharmony_ci    }
245484543d1Sopenharmony_ci    ffrt_task_attr_t *p = const_cast<ffrt_task_attr_t *>(attr);
246484543d1Sopenharmony_ci    return static_cast<ffrt_queue_priority_t>((reinterpret_cast<ffrt::task_attr_private *>(p))->prio_);
247484543d1Sopenharmony_ci}
248484543d1Sopenharmony_ci
249484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
250484543d1Sopenharmony_civoid ffrt_task_attr_set_stack_size(ffrt_task_attr_t* attr, uint64_t size)
251484543d1Sopenharmony_ci{
252484543d1Sopenharmony_ci    if (unlikely(!attr)) {
253484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
254484543d1Sopenharmony_ci        return;
255484543d1Sopenharmony_ci    }
256484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->stackSize_ = size;
257484543d1Sopenharmony_ci}
258484543d1Sopenharmony_ci
259484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
260484543d1Sopenharmony_ciuint64_t ffrt_task_attr_get_stack_size(const ffrt_task_attr_t* attr)
261484543d1Sopenharmony_ci{
262484543d1Sopenharmony_ci    if (unlikely(!attr)) {
263484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
264484543d1Sopenharmony_ci        return 0;
265484543d1Sopenharmony_ci    }
266484543d1Sopenharmony_ci    return (reinterpret_cast<const ffrt::task_attr_private *>(attr))->stackSize_;
267484543d1Sopenharmony_ci}
268484543d1Sopenharmony_ci
269484543d1Sopenharmony_ci// submit
270484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
271484543d1Sopenharmony_civoid *ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind)
272484543d1Sopenharmony_ci{
273484543d1Sopenharmony_ci    if (kind == ffrt_function_kind_general) {
274484543d1Sopenharmony_ci        return ffrt::TaskFactory::Alloc()->func_storage;
275484543d1Sopenharmony_ci    }
276484543d1Sopenharmony_ci    return ffrt::SimpleAllocator<ffrt::QueueTask>::AllocMem()->func_storage;
277484543d1Sopenharmony_ci}
278484543d1Sopenharmony_ci
279484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
280484543d1Sopenharmony_civoid ffrt_submit_base(ffrt_function_header_t *f, const ffrt_deps_t *in_deps, const ffrt_deps_t *out_deps,
281484543d1Sopenharmony_ci    const ffrt_task_attr_t *attr)
282484543d1Sopenharmony_ci{
283484543d1Sopenharmony_ci    if (unlikely(!f)) {
284484543d1Sopenharmony_ci        FFRT_LOGE("function handler should not be empty");
285484543d1Sopenharmony_ci        return;
286484543d1Sopenharmony_ci    }
287484543d1Sopenharmony_ci    ffrt_task_handle_t handle;
288484543d1Sopenharmony_ci    ffrt::task_attr_private *p = reinterpret_cast<ffrt::task_attr_private *>(const_cast<ffrt_task_attr_t *>(attr));
289484543d1Sopenharmony_ci    if (likely(attr == nullptr || ffrt_task_attr_get_delay(attr) == 0)) {
290484543d1Sopenharmony_ci        ffrt::submit_impl(false, handle, f, in_deps, out_deps, p);
291484543d1Sopenharmony_ci        return;
292484543d1Sopenharmony_ci    }
293484543d1Sopenharmony_ci
294484543d1Sopenharmony_ci    // task after delay
295484543d1Sopenharmony_ci    ffrt_task_handle_t delay_handle;
296484543d1Sopenharmony_ci    uint64_t timeout = p->timeout_;
297484543d1Sopenharmony_ci    p->timeout_ = 0;
298484543d1Sopenharmony_ci    ffrt::CreateDelayDeps(delay_handle, in_deps, out_deps, p);
299484543d1Sopenharmony_ci    p->timeout_ = timeout;
300484543d1Sopenharmony_ci    std::vector<ffrt_dependence_t> deps = {{ffrt_dependence_task, delay_handle}};
301484543d1Sopenharmony_ci    ffrt_deps_t delay_deps {static_cast<uint32_t>(deps.size()), deps.data()};
302484543d1Sopenharmony_ci    ffrt::submit_impl(false, handle, f, &delay_deps, nullptr, p);
303484543d1Sopenharmony_ci    ffrt_task_handle_destroy(delay_handle);
304484543d1Sopenharmony_ci}
305484543d1Sopenharmony_ci
306484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
307484543d1Sopenharmony_ciffrt_task_handle_t ffrt_submit_h_base(ffrt_function_header_t *f, const ffrt_deps_t *in_deps,
308484543d1Sopenharmony_ci    const ffrt_deps_t *out_deps, const ffrt_task_attr_t *attr)
309484543d1Sopenharmony_ci{
310484543d1Sopenharmony_ci    if (unlikely(!f)) {
311484543d1Sopenharmony_ci        FFRT_LOGE("function handler should not be empty");
312484543d1Sopenharmony_ci        return nullptr;
313484543d1Sopenharmony_ci    }
314484543d1Sopenharmony_ci    ffrt_task_handle_t handle = nullptr;
315484543d1Sopenharmony_ci    ffrt::task_attr_private *p = reinterpret_cast<ffrt::task_attr_private *>(const_cast<ffrt_task_attr_t *>(attr));
316484543d1Sopenharmony_ci    if (likely(attr == nullptr || ffrt_task_attr_get_delay(attr) == 0)) {
317484543d1Sopenharmony_ci        ffrt::submit_impl(true, handle, f, in_deps, out_deps, p);
318484543d1Sopenharmony_ci        return handle;
319484543d1Sopenharmony_ci    }
320484543d1Sopenharmony_ci
321484543d1Sopenharmony_ci    // task after delay
322484543d1Sopenharmony_ci    ffrt_task_handle_t delay_handle = nullptr;
323484543d1Sopenharmony_ci    uint64_t timeout = p->timeout_;
324484543d1Sopenharmony_ci    p->timeout_ = 0;
325484543d1Sopenharmony_ci    ffrt::CreateDelayDeps(delay_handle, in_deps, out_deps, p);
326484543d1Sopenharmony_ci    p->timeout_ = timeout;
327484543d1Sopenharmony_ci    std::vector<ffrt_dependence_t> deps = {{ffrt_dependence_task, delay_handle}};
328484543d1Sopenharmony_ci    ffrt_deps_t delay_deps {static_cast<uint32_t>(deps.size()), deps.data()};
329484543d1Sopenharmony_ci    ffrt::submit_impl(true, handle, f, &delay_deps, nullptr, p);
330484543d1Sopenharmony_ci    ffrt_task_handle_destroy(delay_handle);
331484543d1Sopenharmony_ci    return handle;
332484543d1Sopenharmony_ci}
333484543d1Sopenharmony_ci
334484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
335484543d1Sopenharmony_ciuint32_t ffrt_task_handle_inc_ref(ffrt_task_handle_t handle)
336484543d1Sopenharmony_ci{
337484543d1Sopenharmony_ci    if (handle == nullptr) {
338484543d1Sopenharmony_ci        FFRT_LOGE("input task handle is invalid");
339484543d1Sopenharmony_ci        return -1;
340484543d1Sopenharmony_ci    }
341484543d1Sopenharmony_ci    return static_cast<ffrt::CPUEUTask*>(handle)->IncDeleteRef();
342484543d1Sopenharmony_ci}
343484543d1Sopenharmony_ci
344484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
345484543d1Sopenharmony_ciuint32_t ffrt_task_handle_dec_ref(ffrt_task_handle_t handle)
346484543d1Sopenharmony_ci{
347484543d1Sopenharmony_ci    if (handle == nullptr) {
348484543d1Sopenharmony_ci        FFRT_LOGE("input task handle is invalid");
349484543d1Sopenharmony_ci        return -1;
350484543d1Sopenharmony_ci    }
351484543d1Sopenharmony_ci    return static_cast<ffrt::CPUEUTask*>(handle)->DecDeleteRef();
352484543d1Sopenharmony_ci}
353484543d1Sopenharmony_ci
354484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
355484543d1Sopenharmony_civoid ffrt_task_handle_destroy(ffrt_task_handle_t handle)
356484543d1Sopenharmony_ci{
357484543d1Sopenharmony_ci    ffrt_task_handle_dec_ref(handle);
358484543d1Sopenharmony_ci}
359484543d1Sopenharmony_ci
360484543d1Sopenharmony_ci// wait
361484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
362484543d1Sopenharmony_civoid ffrt_wait_deps(const ffrt_deps_t *deps)
363484543d1Sopenharmony_ci{
364484543d1Sopenharmony_ci    if (unlikely(!deps)) {
365484543d1Sopenharmony_ci        FFRT_LOGE("deps should not be empty");
366484543d1Sopenharmony_ci        return;
367484543d1Sopenharmony_ci    }
368484543d1Sopenharmony_ci    std::vector<ffrt_dependence_t> v(deps->len);
369484543d1Sopenharmony_ci    for (uint64_t i = 0; i < deps->len; ++i) {
370484543d1Sopenharmony_ci        v[i] = deps->items[i];
371484543d1Sopenharmony_ci    }
372484543d1Sopenharmony_ci    ffrt_deps_t d = { deps->len, v.data() };
373484543d1Sopenharmony_ci    ffrt::FFRTFacade::GetDMInstance().onWait(&d);
374484543d1Sopenharmony_ci}
375484543d1Sopenharmony_ci
376484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
377484543d1Sopenharmony_civoid ffrt_wait()
378484543d1Sopenharmony_ci{
379484543d1Sopenharmony_ci    ffrt::FFRTFacade::GetDMInstance().onWait();
380484543d1Sopenharmony_ci}
381484543d1Sopenharmony_ci
382484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
383484543d1Sopenharmony_ciint ffrt_set_cgroup_attr(ffrt_qos_t qos, ffrt_os_sched_attr *attr)
384484543d1Sopenharmony_ci{
385484543d1Sopenharmony_ci    if (unlikely(!attr)) {
386484543d1Sopenharmony_ci        FFRT_LOGE("attr should not be empty");
387484543d1Sopenharmony_ci        return -1;
388484543d1Sopenharmony_ci    }
389484543d1Sopenharmony_ci    if (ffrt::GetFuncQosMap() == nullptr) {
390484543d1Sopenharmony_ci        FFRT_LOGE("FuncQosMap has not regist");
391484543d1Sopenharmony_ci        return -1;
392484543d1Sopenharmony_ci    }
393484543d1Sopenharmony_ci    ffrt::QoS _qos = ffrt::GetFuncQosMap()(qos);
394484543d1Sopenharmony_ci    return ffrt::OSAttrManager::Instance()->UpdateSchedAttr(_qos, attr);
395484543d1Sopenharmony_ci}
396484543d1Sopenharmony_ci
397484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
398484543d1Sopenharmony_civoid ffrt_restore_qos_config()
399484543d1Sopenharmony_ci{
400484543d1Sopenharmony_ci    ffrt::WorkerGroupCtl *wgCtl = ffrt::FFRTFacade::GetEUInstance().GetGroupCtl();
401484543d1Sopenharmony_ci    for (auto qos = ffrt::QoS::Min(); qos < ffrt::QoS::Max(); ++qos) {
402484543d1Sopenharmony_ci        std::unique_lock<std::shared_mutex> lck(wgCtl[qos].tgMutex);
403484543d1Sopenharmony_ci        for (auto& thread : wgCtl[qos].threads) {
404484543d1Sopenharmony_ci            ffrt::SetThreadAttr(thread.first, qos);
405484543d1Sopenharmony_ci        }
406484543d1Sopenharmony_ci    }
407484543d1Sopenharmony_ci}
408484543d1Sopenharmony_ci
409484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
410484543d1Sopenharmony_ciint ffrt_set_qos_worker_num(ffrt_worker_num_param *qosData)
411484543d1Sopenharmony_ci{
412484543d1Sopenharmony_ci    ffrt::CPUMonitor *monitor = ffrt::FFRTFacade::GetEUInstance().GetCPUMonitor();
413484543d1Sopenharmony_ci    return monitor->QosWorkerNumSegment(qosData);
414484543d1Sopenharmony_ci}
415484543d1Sopenharmony_ci
416484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
417484543d1Sopenharmony_civoid ffrt_notify_workers(ffrt_qos_t qos, int number)
418484543d1Sopenharmony_ci{
419484543d1Sopenharmony_ci    if (qos < ffrt::QoS::Min() || qos >= ffrt::QoS::Max() || number <= 0) {
420484543d1Sopenharmony_ci        FFRT_LOGE("qos [%d] or number [%d] or is invalid.", qos, number);
421484543d1Sopenharmony_ci        return;
422484543d1Sopenharmony_ci    }
423484543d1Sopenharmony_ci
424484543d1Sopenharmony_ci    ffrt::FFRTFacade::GetEUInstance().NotifyWorkers(qos, number);
425484543d1Sopenharmony_ci}
426484543d1Sopenharmony_ci
427484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
428484543d1Sopenharmony_ciffrt_error_t ffrt_set_worker_stack_size(ffrt_qos_t qos, size_t stack_size)
429484543d1Sopenharmony_ci{
430484543d1Sopenharmony_ci    if (qos < ffrt::QoS::Min() || qos >= ffrt::QoS::Max() || stack_size < PTHREAD_STACK_MIN) {
431484543d1Sopenharmony_ci        FFRT_LOGE("qos [%d] or stack size [%d] is invalid.", qos, stack_size);
432484543d1Sopenharmony_ci        return ffrt_error_inval;
433484543d1Sopenharmony_ci    }
434484543d1Sopenharmony_ci
435484543d1Sopenharmony_ci    ffrt::WorkerGroupCtl* groupCtl = ffrt::FFRTFacade::GetEUInstance().GetGroupCtl();
436484543d1Sopenharmony_ci    std::unique_lock<std::shared_mutex> lck(groupCtl[qos].tgMutex);
437484543d1Sopenharmony_ci    if (!groupCtl[qos].threads.empty()) {
438484543d1Sopenharmony_ci        FFRT_LOGE("Stack size can be set only when there is no worker.");
439484543d1Sopenharmony_ci        return ffrt_error;
440484543d1Sopenharmony_ci    }
441484543d1Sopenharmony_ci
442484543d1Sopenharmony_ci    int pageSize = getpagesize();
443484543d1Sopenharmony_ci    if (pageSize < 0) {
444484543d1Sopenharmony_ci        FFRT_LOGE("Invalid pagesize : %d", pageSize);
445484543d1Sopenharmony_ci        return ffrt_error;
446484543d1Sopenharmony_ci    }
447484543d1Sopenharmony_ci
448484543d1Sopenharmony_ci    groupCtl[qos].workerStackSize = (stack_size - 1 + static_cast<size_t>(pageSize)) &
449484543d1Sopenharmony_ci        -(static_cast<size_t>(pageSize));
450484543d1Sopenharmony_ci
451484543d1Sopenharmony_ci    return ffrt_success;
452484543d1Sopenharmony_ci}
453484543d1Sopenharmony_ci
454484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
455484543d1Sopenharmony_ciint ffrt_this_task_update_qos(ffrt_qos_t qos)
456484543d1Sopenharmony_ci{
457484543d1Sopenharmony_ci    if (ffrt::GetFuncQosMap() == nullptr) {
458484543d1Sopenharmony_ci        FFRT_LOGE("FuncQosMap has not regist");
459484543d1Sopenharmony_ci        return 1;
460484543d1Sopenharmony_ci    }
461484543d1Sopenharmony_ci    ffrt::QoS _qos = ffrt::GetFuncQosMap()(qos);
462484543d1Sopenharmony_ci    auto curTask = ffrt::ExecuteCtx::Cur()->task;
463484543d1Sopenharmony_ci    if (curTask == nullptr) {
464484543d1Sopenharmony_ci        FFRT_LOGW("task is nullptr");
465484543d1Sopenharmony_ci        return 1;
466484543d1Sopenharmony_ci    }
467484543d1Sopenharmony_ci
468484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((curTask->type != ffrt_normal_task), return 1, "update qos task type invalid");
469484543d1Sopenharmony_ci    if (_qos() == curTask->qos) {
470484543d1Sopenharmony_ci        FFRT_LOGW("the target qos is equal to current qos, no need update");
471484543d1Sopenharmony_ci        return 0;
472484543d1Sopenharmony_ci    }
473484543d1Sopenharmony_ci
474484543d1Sopenharmony_ci    curTask->SetQos(_qos);
475484543d1Sopenharmony_ci    ffrt_yield();
476484543d1Sopenharmony_ci
477484543d1Sopenharmony_ci    return 0;
478484543d1Sopenharmony_ci}
479484543d1Sopenharmony_ci
480484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
481484543d1Sopenharmony_ciffrt_qos_t ffrt_this_task_get_qos()
482484543d1Sopenharmony_ci{
483484543d1Sopenharmony_ci    if (ffrt::ExecuteCtx::Cur()->task == nullptr) {
484484543d1Sopenharmony_ci        FFRT_LOGW("task is nullptr");
485484543d1Sopenharmony_ci        return static_cast<int>(ffrt_qos_default);
486484543d1Sopenharmony_ci    }
487484543d1Sopenharmony_ci    return ffrt::ExecuteCtx::Cur()->qos();
488484543d1Sopenharmony_ci}
489484543d1Sopenharmony_ci
490484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
491484543d1Sopenharmony_ciuint64_t ffrt_this_task_get_id()
492484543d1Sopenharmony_ci{
493484543d1Sopenharmony_ci    auto curTask = ffrt::ExecuteCtx::Cur()->task;
494484543d1Sopenharmony_ci    if (curTask == nullptr) {
495484543d1Sopenharmony_ci        return 0;
496484543d1Sopenharmony_ci    }
497484543d1Sopenharmony_ci
498484543d1Sopenharmony_ci    if (curTask->type == ffrt_normal_task || curTask->type == ffrt_queue_task) {
499484543d1Sopenharmony_ci        return curTask->gid;
500484543d1Sopenharmony_ci    }
501484543d1Sopenharmony_ci
502484543d1Sopenharmony_ci    return 0;
503484543d1Sopenharmony_ci}
504484543d1Sopenharmony_ci
505484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
506484543d1Sopenharmony_ciint64_t ffrt_this_queue_get_id()
507484543d1Sopenharmony_ci{
508484543d1Sopenharmony_ci    auto curTask = ffrt::ExecuteCtx::Cur()->task;
509484543d1Sopenharmony_ci    if (curTask == nullptr || curTask->type != ffrt_queue_task) {
510484543d1Sopenharmony_ci        // not serial queue task
511484543d1Sopenharmony_ci        return -1;
512484543d1Sopenharmony_ci    }
513484543d1Sopenharmony_ci
514484543d1Sopenharmony_ci    ffrt::QueueTask* task = reinterpret_cast<ffrt::QueueTask*>(curTask);
515484543d1Sopenharmony_ci    return task->GetQueueId();
516484543d1Sopenharmony_ci}
517484543d1Sopenharmony_ci
518484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
519484543d1Sopenharmony_ciint ffrt_skip(ffrt_task_handle_t handle)
520484543d1Sopenharmony_ci{
521484543d1Sopenharmony_ci    return ffrt::FFRTFacade::GetDMInstance().onSkip(handle);
522484543d1Sopenharmony_ci}
523484543d1Sopenharmony_ci
524484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
525484543d1Sopenharmony_civoid ffrt_executor_task_submit(ffrt_executor_task_t* task, const ffrt_task_attr_t* attr)
526484543d1Sopenharmony_ci{
527484543d1Sopenharmony_ci    if (task == nullptr) {
528484543d1Sopenharmony_ci        FFRT_LOGE("function handler should not be empty");
529484543d1Sopenharmony_ci        return;
530484543d1Sopenharmony_ci    }
531484543d1Sopenharmony_ci    ffrt::task_attr_private* p = reinterpret_cast<ffrt::task_attr_private *>(const_cast<ffrt_task_attr_t *>(attr));
532484543d1Sopenharmony_ci    if (likely(attr == nullptr || ffrt_task_attr_get_delay(attr) == 0)) {
533484543d1Sopenharmony_ci        ffrt::FFRTFacade::GetDMInstance().onSubmitUV(task, p);
534484543d1Sopenharmony_ci        return;
535484543d1Sopenharmony_ci    }
536484543d1Sopenharmony_ci    FFRT_LOGE("uv function does not support delay");
537484543d1Sopenharmony_ci}
538484543d1Sopenharmony_ci
539484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
540484543d1Sopenharmony_civoid ffrt_executor_task_register_func(ffrt_executor_task_func func, ffrt_executor_task_type_t type)
541484543d1Sopenharmony_ci{
542484543d1Sopenharmony_ci    ffrt::FuncManager* func_mg = ffrt::FuncManager::Instance();
543484543d1Sopenharmony_ci    func_mg->insert(type, func);
544484543d1Sopenharmony_ci}
545484543d1Sopenharmony_ci
546484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
547484543d1Sopenharmony_ciint ffrt_executor_task_cancel(ffrt_executor_task_t* task, const ffrt_qos_t qos)
548484543d1Sopenharmony_ci{
549484543d1Sopenharmony_ci    if (task == nullptr) {
550484543d1Sopenharmony_ci        FFRT_LOGE("function handler should not be empty");
551484543d1Sopenharmony_ci        return 0;
552484543d1Sopenharmony_ci    }
553484543d1Sopenharmony_ci    ffrt::QoS _qos = qos;
554484543d1Sopenharmony_ci
555484543d1Sopenharmony_ci    ffrt::LinkedList* node = reinterpret_cast<ffrt::LinkedList *>(&task->wq);
556484543d1Sopenharmony_ci    ffrt::FFRTScheduler* sch = ffrt::FFRTFacade::GetSchedInstance();
557484543d1Sopenharmony_ci    bool ret = sch->RemoveNode(node, _qos);
558484543d1Sopenharmony_ci    if (ret) {
559484543d1Sopenharmony_ci        ffrt::FFRTTraceRecord::TaskCancel<ffrt_uv_task>(qos);
560484543d1Sopenharmony_ci    }
561484543d1Sopenharmony_ci    return static_cast<int>(ret);
562484543d1Sopenharmony_ci}
563484543d1Sopenharmony_ci
564484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
565484543d1Sopenharmony_civoid* ffrt_get_cur_task()
566484543d1Sopenharmony_ci{
567484543d1Sopenharmony_ci    return ffrt::ExecuteCtx::Cur()->task;
568484543d1Sopenharmony_ci}
569484543d1Sopenharmony_ci
570484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
571484543d1Sopenharmony_cibool ffrt_get_current_coroutine_stack(void** stack_addr, size_t* size)
572484543d1Sopenharmony_ci{
573484543d1Sopenharmony_ci    if (stack_addr == nullptr || size == nullptr) {
574484543d1Sopenharmony_ci        return false;
575484543d1Sopenharmony_ci    }
576484543d1Sopenharmony_ci
577484543d1Sopenharmony_ci    if (!ffrt::USE_COROUTINE) {
578484543d1Sopenharmony_ci        return false;
579484543d1Sopenharmony_ci    }
580484543d1Sopenharmony_ci    auto curTask = ffrt::ExecuteCtx::Cur()->task;
581484543d1Sopenharmony_ci    if (curTask != nullptr) {
582484543d1Sopenharmony_ci        auto co = curTask->coRoutine;
583484543d1Sopenharmony_ci        if (co) {
584484543d1Sopenharmony_ci            *size = co->stkMem.size;
585484543d1Sopenharmony_ci            *stack_addr = static_cast<void*>(reinterpret_cast<char*>(co) + sizeof(CoRoutine) - 8);
586484543d1Sopenharmony_ci            return true;
587484543d1Sopenharmony_ci        }
588484543d1Sopenharmony_ci    }
589484543d1Sopenharmony_ci    return false;
590484543d1Sopenharmony_ci}
591484543d1Sopenharmony_ci
592484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
593484543d1Sopenharmony_civoid ffrt_task_attr_set_local(ffrt_task_attr_t* attr, bool task_local)
594484543d1Sopenharmony_ci{
595484543d1Sopenharmony_ci    if (unlikely(!attr)) {
596484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
597484543d1Sopenharmony_ci        return;
598484543d1Sopenharmony_ci    }
599484543d1Sopenharmony_ci    (reinterpret_cast<ffrt::task_attr_private *>(attr))->taskLocal_ = task_local;
600484543d1Sopenharmony_ci}
601484543d1Sopenharmony_ci
602484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
603484543d1Sopenharmony_cibool ffrt_task_attr_get_local(ffrt_task_attr_t* attr)
604484543d1Sopenharmony_ci{
605484543d1Sopenharmony_ci    if (unlikely(!attr)) {
606484543d1Sopenharmony_ci        FFRT_LOGE("attr should be a valid address");
607484543d1Sopenharmony_ci        return false;
608484543d1Sopenharmony_ci    }
609484543d1Sopenharmony_ci    return (reinterpret_cast<ffrt::task_attr_private *>(attr))->taskLocal_;
610484543d1Sopenharmony_ci}
611484543d1Sopenharmony_ci
612484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
613484543d1Sopenharmony_cipthread_t ffrt_task_get_tid(void* task_handle)
614484543d1Sopenharmony_ci{
615484543d1Sopenharmony_ci    if (task_handle == nullptr) {
616484543d1Sopenharmony_ci        FFRT_LOGE("invalid task handle");
617484543d1Sopenharmony_ci        return 0;
618484543d1Sopenharmony_ci    }
619484543d1Sopenharmony_ci
620484543d1Sopenharmony_ci    auto task = reinterpret_cast<ffrt::CPUEUTask*>(task_handle);
621484543d1Sopenharmony_ci    return task->runningTid.load();
622484543d1Sopenharmony_ci}
623484543d1Sopenharmony_ci
624484543d1Sopenharmony_ciAPI_ATTRIBUTE((visibility("default")))
625484543d1Sopenharmony_ciuint64_t ffrt_get_cur_cached_task_id()
626484543d1Sopenharmony_ci{
627484543d1Sopenharmony_ci    uint64_t gid = ffrt_this_task_get_id();
628484543d1Sopenharmony_ci    if (gid == 0) {
629484543d1Sopenharmony_ci        return ffrt::ExecuteCtx::Cur()->lastGid_;
630484543d1Sopenharmony_ci    }
631484543d1Sopenharmony_ci
632484543d1Sopenharmony_ci    return gid;
633484543d1Sopenharmony_ci}
634484543d1Sopenharmony_ci#ifdef __cplusplus
635484543d1Sopenharmony_ci}
636484543d1Sopenharmony_ci#endif
637