1 /*
2  * Copyright (c) 2024 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 #include <sys/prctl.h>
17 #include "ThrExecutor.h"
18 #include "hiview_logger.h"
19 
20 DEFINE_LOG_LABEL(0xD002D66, "Hiview-XPerformance");
21 
22 const static std::string MAIN_THREAD_NAME = "XperfMainThr";
23 
ThrExecutor()24 ThrExecutor::ThrExecutor()
25 {
26     ThrTaskContainer* contMain = new ThrTaskContainer();
27     contMain->StartLoop(MAIN_THREAD_NAME.c_str());
28     containers.insert(std::pair<int, ThrTaskContainer*>(MAIN_THR, contMain));
29 }
30 
~ThrExecutor()31 ThrExecutor::~ThrExecutor()
32 {
33     for (std::map<int, ThrTaskContainer*>::iterator it = containers.begin(); it != containers.end(); it++) {
34         ThrTaskContainer* con = it->second;
35         if (con != nullptr) {
36             con->StopLoop();
37         }
38     }
39 }
40 
ValidateNonNull(void * task)41 void ThrExecutor::ValidateNonNull(void* task)
42 {
43     if (task == nullptr) {
44         throw std::invalid_argument("null task");
45     }
46 }
47 
48 class ProcessTimoutWrapperTask : public ITask {
49 public:
ProcessTimoutWrapperTask(ITimeoutExecutor::ITimeoutHandler * evtProcessor,std::string name)50     ProcessTimoutWrapperTask(ITimeoutExecutor::ITimeoutHandler* evtProcessor, std::string name)
51     {
52         this->evtProcessor = evtProcessor;
53         this->name = name;
54     }
55 
Run()56     void Run()
57     {
58         if (evtProcessor != nullptr) {
59             evtProcessor->HandleTimeoutInMainThr(this->name);
60         }
61         delete this;
62     }
63 
GetTaskInfo()64     std::string GetTaskInfo()
65     {
66         return this->taskName;
67     }
68 private:
69     const std::string taskName = "ProcessTimoutWrapperTask";
70     ITimeoutExecutor::ITimeoutHandler* evtProcessor;
71     std::string name;
72 };
73 
ExecuteTimeoutInMainThr(ITimeoutHandler * task,std::string name)74 void ThrExecutor::ExecuteTimeoutInMainThr(ITimeoutHandler* task, std::string name)
75 {
76     ValidateNonNull(task);
77     ThrTaskContainer* con = containers[MAIN_THR];
78     if (con != nullptr) {
79         ITask* evtTask = new ProcessTimoutWrapperTask(task, name);
80         con->PostTask(evtTask);
81     } else {
82         HIVIEW_LOGE("ThrExecutor::ExecuteTimeoutInMainThr main thread task container is null");
83     }
84 }
85 
86 class ProcessAppEvtWrapperTask : public ITask {
87 public:
ProcessAppEvtWrapperTask(IAppThrExecutor::IProcessAppEvtTask * task,const IAppThrExecutor::AppEvtData data)88     ProcessAppEvtWrapperTask(IAppThrExecutor::IProcessAppEvtTask* task, const IAppThrExecutor::AppEvtData data)
89     {
90         this->evtProcessor = task;
91         this->data = data;
92     }
93 
Run()94     void Run()
95     {
96         if (evtProcessor != nullptr) {
97             evtProcessor->ExecuteProcessAppEvtTaskInMainThr(this->data);
98         }
99         delete this;
100     }
101 
GetTaskInfo()102     std::string GetTaskInfo()
103     {
104         return this->taskName + ", " + data.eventName;
105     }
106 private:
107     const std::string taskName = "ProcessAppEvtWrapperTask";
108     IAppThrExecutor::IProcessAppEvtTask* evtProcessor;
109     IAppThrExecutor::AppEvtData data;
110 };
111 
ExecuteHandleEvtInMainThr(IProcessAppEvtTask * task,const AppEvtData & data)112 void ThrExecutor::ExecuteHandleEvtInMainThr(IProcessAppEvtTask* task, const AppEvtData& data)
113 {
114     ValidateNonNull(task);
115     ThrTaskContainer* con = containers[MAIN_THR];
116     if (con != nullptr) {
117         ITask* evtTask = new ProcessAppEvtWrapperTask(task, data);
118         con->PostTask(evtTask);
119     } else {
120         HIVIEW_LOGE("ThrExecutor::ExecuteHandleEvtInMainThr main thread task container is null");
121     }
122 }
123 
124 class ProcessMonitorEvtWrapperTask : public ITask {
125 public:
ProcessMonitorEvtWrapperTask(IMonitorThrExecutor::IHandleMonitorEvt * handleTask,const std::shared_ptr<XperfEvt> evt)126     ProcessMonitorEvtWrapperTask(
127             IMonitorThrExecutor::IHandleMonitorEvt* handleTask, const std::shared_ptr <XperfEvt> evt)
128     {
129         this->handleTask = handleTask;
130         this->evt = evt;
131     }
132 
Run()133     void Run()
134     {
135         if (handleTask != nullptr) {
136             handleTask->HandleMainThrEvt(this->evt);
137         }
138         delete this;
139     }
140 
GetTaskInfo()141     std::string GetTaskInfo()
142     {
143         return this->taskName;
144     }
145 private:
146     const std::string taskName = "ProcessMonitorEvtWrapperTask";
147     IMonitorThrExecutor::IHandleMonitorEvt* handleTask;
148     std::shared_ptr <XperfEvt> evt;
149 };
150 
ExecuteMonitorInMainThr(IHandleMonitorEvt * task,std::shared_ptr<XperfEvt> evt)151 void ThrExecutor::ExecuteMonitorInMainThr(IHandleMonitorEvt* task, std::shared_ptr <XperfEvt> evt)
152 {
153     ValidateNonNull(task);
154     ThrTaskContainer* con = containers[MAIN_THR];
155     if (con != nullptr) {
156         ITask* evtTask = new ProcessMonitorEvtWrapperTask(task, evt);
157         con->PostTask(evtTask);
158     } else {
159         HIVIEW_LOGE("ThrExecutor::ExecuteMonitorInMainThr main thread task container is null");
160     }
161 }