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 CPU_MONITOR_H 17484543d1Sopenharmony_ci#define CPU_MONITOR_H 18484543d1Sopenharmony_ci 19484543d1Sopenharmony_ci#include <atomic> 20484543d1Sopenharmony_ci#include <vector> 21484543d1Sopenharmony_ci#include <functional> 22484543d1Sopenharmony_ci#include <mutex> 23484543d1Sopenharmony_ci#include "qos.h" 24484543d1Sopenharmony_ci#include "cpp/mutex.h" 25484543d1Sopenharmony_ci#include "eu/cpu_manager_interface.h" 26484543d1Sopenharmony_ci#include "c/type_def_ext.h" 27484543d1Sopenharmony_ci#include "util/token.h" 28484543d1Sopenharmony_ci#include "internal_inc/config.h" 29484543d1Sopenharmony_ci#ifdef FFRT_WORKERS_DYNAMIC_SCALING 30484543d1Sopenharmony_ci#include "eu/blockaware.h" 31484543d1Sopenharmony_ci#endif 32484543d1Sopenharmony_ci 33484543d1Sopenharmony_cinamespace ffrt { 34484543d1Sopenharmony_ci 35484543d1Sopenharmony_cistruct WorkerCtrl { 36484543d1Sopenharmony_ci size_t hardLimit = 0; 37484543d1Sopenharmony_ci size_t maxConcurrency = 0; 38484543d1Sopenharmony_ci size_t reserveNum = 0; 39484543d1Sopenharmony_ci int executionNum = 0; 40484543d1Sopenharmony_ci int sleepingWorkerNum = 0; 41484543d1Sopenharmony_ci bool pollWaitFlag = false; 42484543d1Sopenharmony_ci int deepSleepingWorkerNum = 0; 43484543d1Sopenharmony_ci bool hasWorkDeepSleep = false; 44484543d1Sopenharmony_ci bool retryBeforeDeepSleep = true; 45484543d1Sopenharmony_ci std::mutex lock; 46484543d1Sopenharmony_ci}; 47484543d1Sopenharmony_ci 48484543d1Sopenharmony_ciclass CPUMonitor { 49484543d1Sopenharmony_cipublic: 50484543d1Sopenharmony_ci CPUMonitor(CpuMonitorOps&& ops); 51484543d1Sopenharmony_ci CPUMonitor(const CPUMonitor&) = delete; 52484543d1Sopenharmony_ci CPUMonitor& operator=(const CPUMonitor&) = delete; 53484543d1Sopenharmony_ci virtual ~CPUMonitor(); 54484543d1Sopenharmony_ci uint32_t GetMonitorTid() const; 55484543d1Sopenharmony_ci virtual SleepType IntoSleep(const QoS& qos) = 0; 56484543d1Sopenharmony_ci virtual void WakeupCount(const QoS& qos, bool isDeepSleepWork = false); 57484543d1Sopenharmony_ci void IntoDeepSleep(const QoS& qos); 58484543d1Sopenharmony_ci void OutOfDeepSleep(const QoS& qos); 59484543d1Sopenharmony_ci void TimeoutCount(const QoS& qos); 60484543d1Sopenharmony_ci bool IsExceedDeepSleepThreshold(); 61484543d1Sopenharmony_ci void IntoPollWait(const QoS& qos); 62484543d1Sopenharmony_ci void OutOfPollWait(const QoS& qos); 63484543d1Sopenharmony_ci void DoDestroy(const QoS& qos); 64484543d1Sopenharmony_ci#ifdef FFRT_WORKERS_DYNAMIC_SCALING 65484543d1Sopenharmony_ci bool IsExceedRunningThreshold(const QoS& qos); 66484543d1Sopenharmony_ci bool IsBlockAwareInit(void); 67484543d1Sopenharmony_ci void MonitorMain(); 68484543d1Sopenharmony_ci BlockawareWakeupCond* WakeupCond(void); 69484543d1Sopenharmony_ci#endif 70484543d1Sopenharmony_ci virtual void Notify(const QoS& qos, TaskNotifyType notifyType) = 0; 71484543d1Sopenharmony_ci virtual void WorkerInit() = 0; 72484543d1Sopenharmony_ci int QosWorkerNumSegment (ffrt_worker_num_param* qosData); 73484543d1Sopenharmony_ci bool TryAcquirePublicWorkerNum(const QoS& qos); 74484543d1Sopenharmony_ci /* strategy options for handling task notify events */ 75484543d1Sopenharmony_ci static void HandleTaskNotifyDefault(const QoS& qos, void* p, TaskNotifyType notifyType); 76484543d1Sopenharmony_ci int WakedWorkerNum(const QoS& qos); 77484543d1Sopenharmony_ci int SleepingWorkerNum(const QoS& qos); 78484543d1Sopenharmony_ci void NotifyWorkers(const QoS& qos, int number); 79484543d1Sopenharmony_ci bool HasDeepSleepWork(const QoS& qos); 80484543d1Sopenharmony_ci uint32_t monitorTid = 0; 81484543d1Sopenharmony_ciprotected: 82484543d1Sopenharmony_ci WorkerCtrl ctrlQueue[QoS::MaxNum()]; 83484543d1Sopenharmony_ci void PokeAdd(const QoS& qos); 84484543d1Sopenharmony_ci void PokePick(const QoS& qos); 85484543d1Sopenharmony_ci void Poke(const QoS& qos, uint32_t taskCount, TaskNotifyType notifyType); 86484543d1Sopenharmony_ci CpuMonitorOps& GetOps() 87484543d1Sopenharmony_ci { 88484543d1Sopenharmony_ci return ops; 89484543d1Sopenharmony_ci } 90484543d1Sopenharmony_ciprivate: 91484543d1Sopenharmony_ci void SetupMonitor(); 92484543d1Sopenharmony_ci void StartMonitor(); 93484543d1Sopenharmony_ci 94484543d1Sopenharmony_ci std::thread* monitorThread; 95484543d1Sopenharmony_ci CpuMonitorOps ops; 96484543d1Sopenharmony_ci bool setWorkerNum = false; 97484543d1Sopenharmony_ci std::mutex setWorkerNumLock; 98484543d1Sopenharmony_ci void SetWorkerPara(unsigned int& param, unsigned int value); 99484543d1Sopenharmony_ci int SetQosWorkerPara(ffrt_qos_config& qosCfg); 100484543d1Sopenharmony_ci bool QosWorkerNumValid(ffrt_worker_num_param* qosData); 101484543d1Sopenharmony_ci bool LowQosUseReserveWorkerNum(); 102484543d1Sopenharmony_ci bool HighQosUseReserveWorkerNum(); 103484543d1Sopenharmony_ci void ReleasePublicWorkerNum(const QoS& qos); 104484543d1Sopenharmony_ci void LogAllWorkerNum(); 105484543d1Sopenharmony_ci unsigned int globalReserveWorkerNum = 0; 106484543d1Sopenharmony_ci unsigned int lowQosReserveWorkerNum = 0; 107484543d1Sopenharmony_ci unsigned int highQosReserveWorkerNum = 0; 108484543d1Sopenharmony_ci std::unique_ptr<Token> globalReserveWorkerToken = nullptr; 109484543d1Sopenharmony_ci std::unique_ptr<Token> lowQosReserveWorkerToken = nullptr; 110484543d1Sopenharmony_ci std::unique_ptr<Token> highQosReserveWorkerToken = nullptr; 111484543d1Sopenharmony_ci std::unique_ptr<Token> lowQosUseGlobalWorkerToken = nullptr; 112484543d1Sopenharmony_ci std::unique_ptr<Token> highQosUseGlobalWorkerToken = nullptr; 113484543d1Sopenharmony_ci QosWorkerConfig qosWorkerConfig; 114484543d1Sopenharmony_ci#ifdef FFRT_WORKERS_DYNAMIC_SCALING 115484543d1Sopenharmony_ci bool blockAwareInit = false; 116484543d1Sopenharmony_ci bool stopMonitor = false; 117484543d1Sopenharmony_ci unsigned long keyPtr = 0; 118484543d1Sopenharmony_ci int qosMonitorMaxNum = std::min(QoS::Max(), BLOCKAWARE_DOMAIN_ID_MAX + 1); 119484543d1Sopenharmony_ci BlockawareWakeupCond wakeupCond; 120484543d1Sopenharmony_ci BlockawareDomainInfoArea domainInfoMonitor; 121484543d1Sopenharmony_ci BlockawareDomainInfoArea domainInfoNotify; 122484543d1Sopenharmony_ci std::atomic<bool> exceedUpperWaterLine[QoS::MaxNum()]; 123484543d1Sopenharmony_ci#endif 124484543d1Sopenharmony_ci}; 125484543d1Sopenharmony_ci} 126484543d1Sopenharmony_ci#endif /* CPU_MONITOR_H */ 127