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#ifndef FFRT_DEPENDENCE_MANAGER_H 17484543d1Sopenharmony_ci#define FFRT_DEPENDENCE_MANAGER_H 18484543d1Sopenharmony_ci#include <unordered_map> 19484543d1Sopenharmony_ci#include <vector> 20484543d1Sopenharmony_ci#include <string> 21484543d1Sopenharmony_ci#include <mutex> 22484543d1Sopenharmony_ci#include <shared_mutex> 23484543d1Sopenharmony_ci#include "internal_inc/types.h" 24484543d1Sopenharmony_ci#include "internal_inc/osal.h" 25484543d1Sopenharmony_ci#include "core/version_ctx.h" 26484543d1Sopenharmony_ci#include "sched/execute_ctx.h" 27484543d1Sopenharmony_ci#include "qos.h" 28484543d1Sopenharmony_ci#include "ffrt_trace.h" 29484543d1Sopenharmony_ci#include "sched/task_state.h" 30484543d1Sopenharmony_ci#include "sched/scheduler.h" 31484543d1Sopenharmony_ci#include "eu/execute_unit.h" 32484543d1Sopenharmony_ci#include "core/entity.h" 33484543d1Sopenharmony_ci#include "dfx/watchdog/watchdog_util.h" 34484543d1Sopenharmony_ci#include "dfx/trace_record/ffrt_trace_record.h" 35484543d1Sopenharmony_ci#include "tm/cpu_task.h" 36484543d1Sopenharmony_ci 37484543d1Sopenharmony_cinamespace ffrt { 38484543d1Sopenharmony_ci#define OFFSETOF(TYPE, MEMBER) (reinterpret_cast<size_t>(&((reinterpret_cast<TYPE *>(0))->MEMBER))) 39484543d1Sopenharmony_ci 40484543d1Sopenharmony_ciinline bool CheckOutsHandle(const ffrt_deps_t* outs) 41484543d1Sopenharmony_ci{ 42484543d1Sopenharmony_ci if (outs == nullptr) { 43484543d1Sopenharmony_ci return true; 44484543d1Sopenharmony_ci } 45484543d1Sopenharmony_ci for (uint32_t i = 0; i < outs->len; i++) { 46484543d1Sopenharmony_ci if ((outs->items[i].type) == ffrt_dependence_task) { 47484543d1Sopenharmony_ci FFRT_LOGE("handle can't be used as out dependence"); 48484543d1Sopenharmony_ci return false; 49484543d1Sopenharmony_ci } 50484543d1Sopenharmony_ci } 51484543d1Sopenharmony_ci return true; 52484543d1Sopenharmony_ci} 53484543d1Sopenharmony_ciinline void OutsDedup(std::vector<const void *>& outsNoDup, const ffrt_deps_t* outs) 54484543d1Sopenharmony_ci{ 55484543d1Sopenharmony_ci for (uint32_t i = 0; i < outs->len; i++) { 56484543d1Sopenharmony_ci if (std::find(outsNoDup.begin(), outsNoDup.end(), outs->items[i].ptr) == outsNoDup.end()) { 57484543d1Sopenharmony_ci outsNoDup.push_back(outs->items[i].ptr); 58484543d1Sopenharmony_ci } 59484543d1Sopenharmony_ci } 60484543d1Sopenharmony_ci} 61484543d1Sopenharmony_ci 62484543d1Sopenharmony_ciinline void InsDedup(std::vector<CPUEUTask*> &in_handles, std::vector<const void *> &insNoDup, 63484543d1Sopenharmony_ci std::vector<const void *> &outsNoDup, const ffrt_deps_t *ins) 64484543d1Sopenharmony_ci{ 65484543d1Sopenharmony_ci for (uint32_t i = 0; i < ins->len; i++) { 66484543d1Sopenharmony_ci if (std::find(outsNoDup.begin(), outsNoDup.end(), ins->items[i].ptr) == outsNoDup.end()) { 67484543d1Sopenharmony_ci if ((ins->items[i].type) == ffrt_dependence_task) { 68484543d1Sopenharmony_ci static_cast<ffrt::CPUEUTask*>(const_cast<void*>(ins->items[i].ptr))->IncDeleteRef(); 69484543d1Sopenharmony_ci in_handles.emplace_back(static_cast<ffrt::CPUEUTask*>(const_cast<void*>(ins->items[i].ptr))); 70484543d1Sopenharmony_ci } 71484543d1Sopenharmony_ci insNoDup.push_back(ins->items[i].ptr); 72484543d1Sopenharmony_ci } 73484543d1Sopenharmony_ci } 74484543d1Sopenharmony_ci} 75484543d1Sopenharmony_ci 76484543d1Sopenharmony_ciclass DependenceManager : public NonCopyable { 77484543d1Sopenharmony_cipublic: 78484543d1Sopenharmony_ci static DependenceManager& Instance(); 79484543d1Sopenharmony_ci 80484543d1Sopenharmony_ci static void RegistInsCb(SingleInsCB<DependenceManager>::Instance &&cb); 81484543d1Sopenharmony_ci 82484543d1Sopenharmony_ci virtual void onSubmit(bool has_handle, ffrt_task_handle_t &handle, ffrt_function_header_t *f, 83484543d1Sopenharmony_ci const ffrt_deps_t *ins, const ffrt_deps_t *outs, const task_attr_private *attr) = 0; 84484543d1Sopenharmony_ci 85484543d1Sopenharmony_ci void onSubmitUV(ffrt_executor_task_t *task, const task_attr_private *attr) 86484543d1Sopenharmony_ci { 87484543d1Sopenharmony_ci FFRT_EXECUTOR_TASK_SUBMIT_MARKER(task); 88484543d1Sopenharmony_ci FFRT_TRACE_SCOPE(1, onSubmitUV); 89484543d1Sopenharmony_ci QoS qos = ((attr == nullptr || attr->qos_ == qos_inherit) ? QoS() : QoS(attr->qos_)); 90484543d1Sopenharmony_ci FFRTTraceRecord::TaskSubmit<ffrt_uv_task>(qos); 91484543d1Sopenharmony_ci LinkedList* node = reinterpret_cast<LinkedList *>(&task->wq); 92484543d1Sopenharmony_ci FFRTScheduler* sch = FFRTScheduler::Instance(); 93484543d1Sopenharmony_ci if (!sch->InsertNode(node, qos)) { 94484543d1Sopenharmony_ci FFRT_LOGE("Submit UV task failed!"); 95484543d1Sopenharmony_ci return; 96484543d1Sopenharmony_ci } 97484543d1Sopenharmony_ci FFRTTraceRecord::TaskEnqueue<ffrt_uv_task>(qos); 98484543d1Sopenharmony_ci } 99484543d1Sopenharmony_ci 100484543d1Sopenharmony_ci virtual void onWait() = 0; 101484543d1Sopenharmony_ci#ifdef QOS_DEPENDENCY 102484543d1Sopenharmony_ci virtual void onWait(const ffrt_deps_t* deps, int64_t deadline = -1) = 0; 103484543d1Sopenharmony_ci#else 104484543d1Sopenharmony_ci virtual void onWait(const ffrt_deps_t* deps) = 0; 105484543d1Sopenharmony_ci#endif 106484543d1Sopenharmony_ci 107484543d1Sopenharmony_ci virtual int onExecResults(ffrt_task_handle_t handle) = 0; 108484543d1Sopenharmony_ci 109484543d1Sopenharmony_ci virtual void onTaskDone(CPUEUTask* task) = 0; 110484543d1Sopenharmony_ci 111484543d1Sopenharmony_ci virtual int onSkip(ffrt_task_handle_t handle) = 0; 112484543d1Sopenharmony_ci 113484543d1Sopenharmony_ci static inline CPUEUTask* Root() 114484543d1Sopenharmony_ci { 115484543d1Sopenharmony_ci // Within an ffrt process, different threads may have different QoS interval 116484543d1Sopenharmony_ci thread_local static RootTaskCtxWrapper root_wraper; 117484543d1Sopenharmony_ci return root_wraper.Root(); 118484543d1Sopenharmony_ci } 119484543d1Sopenharmony_ci 120484543d1Sopenharmony_ciprotected: 121484543d1Sopenharmony_ci DependenceManager() {} 122484543d1Sopenharmony_ci virtual ~DependenceManager() {} 123484543d1Sopenharmony_ci}; 124484543d1Sopenharmony_ci 125484543d1Sopenharmony_ci} // namespace ffrt 126484543d1Sopenharmony_ci#endif 127