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