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_strategy.h" 26 #ifdef FFRT_WORKERS_DYNAMIC_SCALING 27 #include "eu/blockaware.h" 28 #endif 29 #include "sync/sync.h" 30 31 namespace ffrt { 32 struct WorkerCtrl { 33 alignas(cacheline_size) fast_mutex lock; 34 alignas(cacheline_size) int executionNum = 0; 35 alignas(cacheline_size) int sleepingWorkerNum = 0; 36 alignas(cacheline_size) bool irqEnable = false; 37 size_t hardLimit = 0; 38 size_t maxConcurrency = 0; 39 bool pollWaitFlag = false; 40 int deepSleepingWorkerNum = 0; 41 bool retryBeforeDeepSleep = true; 42 }; 43 44 class CPUMonitor { 45 public: 46 CPUMonitor(CpuMonitorOps&& ops); 47 CPUMonitor(const CPUMonitor&) = delete; 48 CPUMonitor& operator=(const CPUMonitor&) = delete; 49 virtual ~CPUMonitor(); 50 uint32_t GetMonitorTid() const; 51 int TotalCount(const QoS& qos); 52 virtual void IntoSleep(const QoS& qos) = 0; 53 virtual void IntoPollWait(const QoS& qos) = 0; 54 55 void WakeupSleep(const QoS& qos, bool irqWake = false); 56 void IntoDeepSleep(const QoS& qos); 57 void WakeupDeepSleep(const QoS& qos, bool irqWake = false); 58 void TimeoutCount(const QoS& qos); 59 bool IsExceedDeepSleepThreshold(); 60 void OutOfPollWait(const QoS& qos); 61 void RollbackDestroy(const QoS& qos, bool irqWake = false); 62 bool TryDestroy(const QoS& qos); 63 #ifdef FFRT_WORKERS_DYNAMIC_SCALING 64 bool IsExceedRunningThreshold(const QoS& qos); 65 bool IsBlockAwareInit(void); 66 void MonitorMain(); 67 BlockawareWakeupCond* WakeupCond(void); 68 #endif 69 virtual void Notify(const QoS& qos, TaskNotifyType notifyType) = 0; 70 virtual void WorkerInit() = 0; 71 int SetWorkerMaxNum(const QoS& qos, int num); 72 /* strategy options for handling task notify events */ 73 static void HandleTaskNotifyDefault(const QoS& qos, void* p, TaskNotifyType notifyType); 74 static void HandleTaskNotifyConservative(const QoS& qos, void* p, TaskNotifyType notifyType); 75 static void HandleTaskNotifyUltraConservative(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 void StartMonitor(); 80 81 CpuMonitorOps ops; 82 std::thread* monitorThread = nullptr; 83 uint32_t monitorTid = 0; 84 protected: 85 WorkerCtrl ctrlQueue[QoS::MaxNum()]; 86 void Poke(const QoS& qos, uint32_t taskCount, TaskNotifyType notifyType); GetOps()87 CpuMonitorOps& GetOps() 88 { 89 return ops; 90 } 91 #ifdef FFRT_WORKERS_DYNAMIC_SCALING 92 bool blockAwareInit = false; 93 bool stopMonitor = false; 94 unsigned long keyPtr = 0; 95 int qosMonitorMaxNum = std::min(QoS::Max(), BLOCKAWARE_DOMAIN_ID_MAX + 1); 96 BlockawareWakeupCond wakeupCond; 97 BlockawareDomainInfoArea domainInfoMonitor; 98 #endif 99 private: 100 void SetupMonitor(); 101 std::atomic<bool> setWorkerMaxNum[QoS::MaxNum()]; 102 }; 103 } 104 #endif /* CPU_MONITOR_H */