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