1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef CPU_MONITOR_H 17 #define CPU_MONITOR_H 18 19 #include <atomic> 20 #include <vector> 21 #include <functional> 22 #include <mutex> 23 #include "qos.h" 24 #include "cpp/mutex.h" 25 #include "eu/cpu_manager_interface.h" 26 #include "c/type_def_ext.h" 27 #include "util/token.h" 28 #include "internal_inc/config.h" 29 #ifdef FFRT_WORKERS_DYNAMIC_SCALING 30 #include "eu/blockaware.h" 31 #endif 32 33 namespace ffrt { 34 35 struct WorkerCtrl { 36 size_t hardLimit = 0; 37 size_t maxConcurrency = 0; 38 size_t reserveNum = 0; 39 int executionNum = 0; 40 int sleepingWorkerNum = 0; 41 bool pollWaitFlag = false; 42 int deepSleepingWorkerNum = 0; 43 bool hasWorkDeepSleep = false; 44 bool retryBeforeDeepSleep = true; 45 std::mutex lock; 46 }; 47 48 class CPUMonitor { 49 public: 50 CPUMonitor(CpuMonitorOps&& ops); 51 CPUMonitor(const CPUMonitor&) = delete; 52 CPUMonitor& operator=(const CPUMonitor&) = delete; 53 virtual ~CPUMonitor(); 54 uint32_t GetMonitorTid() const; 55 virtual SleepType IntoSleep(const QoS& qos) = 0; 56 virtual void WakeupCount(const QoS& qos, bool isDeepSleepWork = false); 57 void IntoDeepSleep(const QoS& qos); 58 void OutOfDeepSleep(const QoS& qos); 59 void TimeoutCount(const QoS& qos); 60 bool IsExceedDeepSleepThreshold(); 61 void IntoPollWait(const QoS& qos); 62 void OutOfPollWait(const QoS& qos); 63 void DoDestroy(const QoS& qos); 64 #ifdef FFRT_WORKERS_DYNAMIC_SCALING 65 bool IsExceedRunningThreshold(const QoS& qos); 66 bool IsBlockAwareInit(void); 67 void MonitorMain(); 68 BlockawareWakeupCond* WakeupCond(void); 69 #endif 70 virtual void Notify(const QoS& qos, TaskNotifyType notifyType) = 0; 71 virtual void WorkerInit() = 0; 72 int QosWorkerNumSegment (ffrt_worker_num_param* qosData); 73 bool TryAcquirePublicWorkerNum(const QoS& qos); 74 /* strategy options for handling task notify events */ 75 static void HandleTaskNotifyDefault(const QoS& qos, void* p, TaskNotifyType notifyType); 76 int WakedWorkerNum(const QoS& qos); 77 int SleepingWorkerNum(const QoS& qos); 78 void NotifyWorkers(const QoS& qos, int number); 79 bool HasDeepSleepWork(const QoS& qos); 80 uint32_t monitorTid = 0; 81 protected: 82 WorkerCtrl ctrlQueue[QoS::MaxNum()]; 83 void PokeAdd(const QoS& qos); 84 void PokePick(const QoS& qos); 85 void Poke(const QoS& qos, uint32_t taskCount, TaskNotifyType notifyType); GetOps()86 CpuMonitorOps& GetOps() 87 { 88 return ops; 89 } 90 private: 91 void SetupMonitor(); 92 void StartMonitor(); 93 94 std::thread* monitorThread; 95 CpuMonitorOps ops; 96 bool setWorkerNum = false; 97 std::mutex setWorkerNumLock; 98 void SetWorkerPara(unsigned int& param, unsigned int value); 99 int SetQosWorkerPara(ffrt_qos_config& qosCfg); 100 bool QosWorkerNumValid(ffrt_worker_num_param* qosData); 101 bool LowQosUseReserveWorkerNum(); 102 bool HighQosUseReserveWorkerNum(); 103 void ReleasePublicWorkerNum(const QoS& qos); 104 void LogAllWorkerNum(); 105 unsigned int globalReserveWorkerNum = 0; 106 unsigned int lowQosReserveWorkerNum = 0; 107 unsigned int highQosReserveWorkerNum = 0; 108 std::unique_ptr<Token> globalReserveWorkerToken = nullptr; 109 std::unique_ptr<Token> lowQosReserveWorkerToken = nullptr; 110 std::unique_ptr<Token> highQosReserveWorkerToken = nullptr; 111 std::unique_ptr<Token> lowQosUseGlobalWorkerToken = nullptr; 112 std::unique_ptr<Token> highQosUseGlobalWorkerToken = nullptr; 113 QosWorkerConfig qosWorkerConfig; 114 #ifdef FFRT_WORKERS_DYNAMIC_SCALING 115 bool blockAwareInit = false; 116 bool stopMonitor = false; 117 unsigned long keyPtr = 0; 118 int qosMonitorMaxNum = std::min(QoS::Max(), BLOCKAWARE_DOMAIN_ID_MAX + 1); 119 BlockawareWakeupCond wakeupCond; 120 BlockawareDomainInfoArea domainInfoMonitor; 121 BlockawareDomainInfoArea domainInfoNotify; 122 std::atomic<bool> exceedUpperWaterLine[QoS::MaxNum()]; 123 #endif 124 }; 125 } 126 #endif /* CPU_MONITOR_H */ 127