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 <deque> 20 #include <mutex> 21 #include <map> 22 #include "eu/cpu_worker.h" 23 #include "tm/task_base.h" 24 25 namespace ffrt { 26 struct TaskTimeoutInfo { 27 TaskBase* task_ = nullptr; 28 int recordLevel_ = 0; 29 int sampledTimes_ = 0; 30 int executionTime_ = 0; 31 TaskTimeoutInfoTaskTimeoutInfo32 TaskTimeoutInfo() {} TaskTimeoutInfoTaskTimeoutInfo33 explicit TaskTimeoutInfo(TaskBase* task) : task_(task) {} 34 }; 35 36 struct CoWorkerInfo { 37 size_t qosLevel_; 38 int coWorkerCount_; 39 int executionNum_; 40 int sleepingWorkerNum_; 41 CoWorkerInfoCoWorkerInfo42 CoWorkerInfo(size_t qosLevel, int coWorkerCount, int executionNum, int sleepingWorkerNum) 43 : qosLevel_(qosLevel), coWorkerCount_(coWorkerCount), 44 executionNum_(executionNum), sleepingWorkerNum_(sleepingWorkerNum) {} 45 }; 46 47 struct WorkerInfo { 48 int tid_; 49 uint64_t gid_; 50 uintptr_t workerTaskType_; 51 std::string label_; 52 WorkerInfoWorkerInfo53 WorkerInfo(int workerId, uint64_t taskId, uintptr_t workerTaskType, std::string workerTaskLabel) 54 : tid_(workerId), gid_(taskId), workerTaskType_(workerTaskType), label_(workerTaskLabel) {} 55 }; 56 57 struct TimeoutFunctionInfo { 58 CoWorkerInfo coWorkerInfo_; 59 WorkerInfo workerInfo_; 60 int executionTime_; 61 TimeoutFunctionInfoTimeoutFunctionInfo62 TimeoutFunctionInfo(const CoWorkerInfo& coWorkerInfo, const WorkerInfo& workerInfo, int executionTime) 63 : coWorkerInfo_(coWorkerInfo), workerInfo_(workerInfo), executionTime_(executionTime) 64 { 65 if (workerInfo_.workerTaskType_ != ffrt_normal_task && workerInfo_.workerTaskType_ != ffrt_queue_task) { 66 workerInfo_.gid_ = UINT64_MAX; // 该task type 没有 gid 67 workerInfo_.label_ = "Unsupport_Task_type"; // 该task type 没有 label 68 } 69 } 70 }; 71 72 class WorkerMonitor { 73 public: 74 static WorkerMonitor &GetInstance(); 75 void SubmitTask(); 76 std::string DumpTimeoutInfo(); 77 78 private: 79 WorkerMonitor(); 80 ~WorkerMonitor(); 81 WorkerMonitor(const WorkerMonitor &) = delete; 82 WorkerMonitor(WorkerMonitor &&) = delete; 83 WorkerMonitor &operator=(const WorkerMonitor &) = delete; 84 WorkerMonitor &operator=(WorkerMonitor &&) = delete; 85 void SubmitSamplingTask(); 86 void SubmitTaskMonitor(uint64_t nextTimeoutUs); 87 void SubmitMemReleaseTask(); 88 void CheckWorkerStatus(); 89 void CheckTaskStatus(); 90 uint64_t CalculateTaskTimeout(CPUEUTask* task, uint64_t timeoutThreshold); 91 bool ControlTimeoutFreq(CPUEUTask* task); 92 void RecordTimeoutTaskInfo(CPUEUTask* task); 93 void RecordTimeoutFunctionInfo(const CoWorkerInfo& coWorkerInfo, CPUWorker* worker, 94 TaskBase* workerTask, std::vector<TimeoutFunctionInfo>& timeoutFunctions); 95 void RecordSymbolAndBacktrace(const TimeoutFunctionInfo& timeoutFunction); 96 void RecordIpcInfo(const std::string& dumpInfo, int tid); 97 void RecordKeyInfo(const std::string& dumpInfo); 98 void ProcessWorkerInfo(std::ostringstream& oss, bool& firstQos, int qos, unsigned int cnt, 99 const std::deque<pid_t>& tids); 100 void RecordWorkerStatusInfo(); 101 102 private: 103 std::mutex mutex_; 104 std::mutex submitTaskMutex_; 105 bool skipSampling_ = false; 106 uint64_t timeoutUs_ = 0; 107 std::vector<std::pair<uint64_t, std::string>> taskTimeoutInfo_; 108 WaitUntilEntry watchdogWaitEntry_; 109 WaitUntilEntry tskMonitorWaitEntry_; 110 WaitUntilEntry memReleaseWaitEntry_; 111 std::map<CPUWorker*, TaskTimeoutInfo> workerStatus_; 112 bool samplingTaskExit_ = true; 113 bool taskMonitorExit_ = true; 114 bool memReleaseTaskExit_ = true; 115 unsigned int samplingTaskCount_ = 0; 116 }; 117 } 118 #endif