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_VERSION_CTX_H 17484543d1Sopenharmony_ci#define FFRT_VERSION_CTX_H 18484543d1Sopenharmony_ci#include <unordered_set> 19484543d1Sopenharmony_ci#include <vector> 20484543d1Sopenharmony_ci#include <string> 21484543d1Sopenharmony_ci 22484543d1Sopenharmony_ci#include "internal_inc/types.h" 23484543d1Sopenharmony_ci#include "tm/scpu_task.h" 24484543d1Sopenharmony_cinamespace ffrt { 25484543d1Sopenharmony_ci/* The relationship of VersionCtx is implemented using a doubly linked list: 26484543d1Sopenharmony_ci * 0、data represents the root node of this data signature 27484543d1Sopenharmony_ci * 1、Non-nested scenes: v1<—>v2<—>v3<—>data 28484543d1Sopenharmony_ci * 2、Nested scenes: v1<—>v2.1<—>v2.2<—>v2<—>v3<—>data 29484543d1Sopenharmony_ci */ 30484543d1Sopenharmony_ci 31484543d1Sopenharmony_cistruct VersionCtx : private NonCopyable { 32484543d1Sopenharmony_ci VersionCtx(const void* signature, VersionCtx* next, VersionCtx* last) 33484543d1Sopenharmony_ci : signature(signature), next(next), last(last) {}; 34484543d1Sopenharmony_ci // Unique identifier for the data, taking the memory address of the actual data 35484543d1Sopenharmony_ci const void* signature; 36484543d1Sopenharmony_ci 37484543d1Sopenharmony_ci // Nested scenes, is next version, in non-nested scenes, is the next sub version's parent version 38484543d1Sopenharmony_ci VersionCtx* next {nullptr}; 39484543d1Sopenharmony_ci // Non-nested scenes, is last version, in nested scenes, is the parent's last sub version 40484543d1Sopenharmony_ci VersionCtx* last {nullptr}; 41484543d1Sopenharmony_ci 42484543d1Sopenharmony_ci // Current version's consumers, notify all when ready 43484543d1Sopenharmony_ci std::unordered_set<SCPUEUTask*> consumers; 44484543d1Sopenharmony_ci // Current version's producer 45484543d1Sopenharmony_ci SCPUEUTask* myProducer {nullptr}; 46484543d1Sopenharmony_ci // Next version's producer, notify when consumed 47484543d1Sopenharmony_ci SCPUEUTask* nextProducer {nullptr}; 48484543d1Sopenharmony_ci 49484543d1Sopenharmony_ci DataStatus status {DataStatus::IDLE}; 50484543d1Sopenharmony_ci std::vector<SCPUEUTask*> dataWaitTaskByThis; 51484543d1Sopenharmony_ci 52484543d1Sopenharmony_ci void AddConsumer(SCPUEUTask* consumer, NestType nestType); 53484543d1Sopenharmony_ci void AddProducer(SCPUEUTask* producer); 54484543d1Sopenharmony_ci inline void AddDataWaitTaskByThis(SCPUEUTask* dataWaitTask) 55484543d1Sopenharmony_ci { 56484543d1Sopenharmony_ci if (last != nullptr && last->status == DataStatus::IDLE) { 57484543d1Sopenharmony_ci auto waitVersion = last; 58484543d1Sopenharmony_ci waitVersion->dataWaitTaskByThis.push_back(dataWaitTask); 59484543d1Sopenharmony_ci dataWaitTask->IncWaitDataRef(); 60484543d1Sopenharmony_ci } 61484543d1Sopenharmony_ci } 62484543d1Sopenharmony_ci void onProduced(); 63484543d1Sopenharmony_ci void onConsumed(SCPUEUTask* consumer); 64484543d1Sopenharmony_ciprotected: 65484543d1Sopenharmony_ci void CreateChildVersion(SCPUEUTask* task, DataStatus dataStatus); 66484543d1Sopenharmony_ci void MergeChildVersion(); 67484543d1Sopenharmony_ci inline void NotifyDataWaitTask() 68484543d1Sopenharmony_ci { 69484543d1Sopenharmony_ci for (auto& dataWaitTask : std::as_const(dataWaitTaskByThis)) { 70484543d1Sopenharmony_ci dataWaitTask->DecWaitDataRef(); 71484543d1Sopenharmony_ci } 72484543d1Sopenharmony_ci dataWaitTaskByThis.clear(); 73484543d1Sopenharmony_ci } 74484543d1Sopenharmony_ci 75484543d1Sopenharmony_ci inline void NotifyConsumers() 76484543d1Sopenharmony_ci { 77484543d1Sopenharmony_ci for (auto consumer : std::as_const(consumers)) { 78484543d1Sopenharmony_ci consumer->DecDepRef(); 79484543d1Sopenharmony_ci } 80484543d1Sopenharmony_ci } 81484543d1Sopenharmony_ci 82484543d1Sopenharmony_ci inline void NotifyNextProducer() 83484543d1Sopenharmony_ci { 84484543d1Sopenharmony_ci if (nextProducer != nullptr) { 85484543d1Sopenharmony_ci nextProducer->DecDepRef(); 86484543d1Sopenharmony_ci nextProducer = nullptr; 87484543d1Sopenharmony_ci } 88484543d1Sopenharmony_ci } 89484543d1Sopenharmony_ci 90484543d1Sopenharmony_ci inline void MergeConsumerInDep(VersionCtx* v) 91484543d1Sopenharmony_ci { 92484543d1Sopenharmony_ci for (const auto& consumer : std::as_const(v->consumers)) { 93484543d1Sopenharmony_ci consumer->ins.insert(this); 94484543d1Sopenharmony_ci consumer->ins.erase(consumer->ins.find(v)); 95484543d1Sopenharmony_ci } 96484543d1Sopenharmony_ci } 97484543d1Sopenharmony_ci 98484543d1Sopenharmony_ci inline void MergeProducerOutDep(VersionCtx* v) 99484543d1Sopenharmony_ci { 100484543d1Sopenharmony_ci v->myProducer->outs.insert(this); 101484543d1Sopenharmony_ci v->myProducer->outs.erase(v->myProducer->outs.find(v)); 102484543d1Sopenharmony_ci } 103484543d1Sopenharmony_ci}; 104484543d1Sopenharmony_ci} /* namespace ffrt */ 105484543d1Sopenharmony_ci#endif