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 FFRT_WORKER_MONITOR_H
17 #define FFRT_WORKER_MONITOR_H
18 
19 #include <mutex>
20 #include <map>
21 #include "eu/worker_thread.h"
22 #include "tm/cpu_task.h"
23 
24 namespace ffrt {
25 struct TaskTimeoutInfo {
26     CPUEUTask* task_ = nullptr;
27     int recordLevel_ = 0;
28     int sampledTimes_ = 0;
29     int executionTime_ = 0;
30 
TaskTimeoutInfoTaskTimeoutInfo31     TaskTimeoutInfo() {}
TaskTimeoutInfoTaskTimeoutInfo32     explicit TaskTimeoutInfo(CPUEUTask* task) : task_(task) {}
33 };
34 
35 struct CoWorkerInfo {
36     size_t qosLevel_;
37     int coWorkerCount_;
38     int executionNum_;
39     int sleepingWorkerNum_;
40 
CoWorkerInfoCoWorkerInfo41     CoWorkerInfo(size_t qosLevel, int coWorkerCount, int executionNum, int sleepingWorkerNum)
42         : qosLevel_(qosLevel), coWorkerCount_(coWorkerCount),
43         executionNum_(executionNum), sleepingWorkerNum_(sleepingWorkerNum) {}
44 };
45 
46 struct WorkerInfo {
47     int tid_;
48     uint64_t gid_;
49     uintptr_t workerTaskType_;
50     std::string label_;
51 
WorkerInfoWorkerInfo52     WorkerInfo(int workerId, uint64_t taskId, uintptr_t workerTaskType, std::string workerTaskLabel)
53         : tid_(workerId), gid_(taskId), workerTaskType_(workerTaskType), label_(workerTaskLabel) {}
54 };
55 
56 struct TimeoutFunctionInfo {
57     CoWorkerInfo coWorkerInfo_;
58     WorkerInfo workerInfo_;
59     int executionTime_;
60 
TimeoutFunctionInfoTimeoutFunctionInfo61     TimeoutFunctionInfo(const CoWorkerInfo& coWorkerInfo, const WorkerInfo& workerInfo, int executionTime)
62         : coWorkerInfo_(coWorkerInfo), workerInfo_(workerInfo), executionTime_(executionTime)
63     {
64         if (workerInfo_.workerTaskType_ != ffrt_normal_task && workerInfo_.workerTaskType_ != ffrt_queue_task) {
65             workerInfo_.gid_ = UINT64_MAX; // 该task type 没有 gid
66             workerInfo_.label_ = "Unsupport_Task_type"; // 该task type 没有 label
67         }
68     }
69 };
70 
71 class WorkerMonitor {
72 public:
73     static WorkerMonitor &GetInstance();
74     void SubmitTask();
75 
76 private:
77     WorkerMonitor();
78     ~WorkerMonitor();
79     WorkerMonitor(const WorkerMonitor &) = delete;
80     WorkerMonitor(WorkerMonitor &&) = delete;
81     WorkerMonitor &operator=(const WorkerMonitor &) = delete;
82     WorkerMonitor &operator=(WorkerMonitor &&) = delete;
83     void SubmitSamplingTask();
84     void SubmitMemReleaseTask();
85     void CheckWorkerStatus();
86     void RecordTimeoutFunctionInfo(const CoWorkerInfo& coWorkerInfo, WorkerThread* worker,
87         CPUEUTask* workerTask, std::vector<TimeoutFunctionInfo>& timeoutFunctions);
88     void RecordSymbolAndBacktrace(const TimeoutFunctionInfo& timeoutFunction);
89     void RecordIpcInfo(const std::string& dumpInfo, int tid);
90     void RecordKeyInfo(const std::string& dumpInfo);
91 
92 private:
93     std::mutex mutex_;
94     std::mutex submitTaskMutex_;
95     bool skipSampling_ = false;
96     WaitUntilEntry watchdogWaitEntry_;
97     WaitUntilEntry memReleaseWaitEntry_;
98     std::map<WorkerThread*, TaskTimeoutInfo> workerStatus_;
99     bool samplingTaskExit_ = true;
100     bool memReleaseTaskExit_ = true;
101 };
102 }
103 #endif