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