• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #ifndef HIPERF_CLIENT_H_
16 #define HIPERF_CLIENT_H_
17 
18 #include <chrono>
19 #include <string>
20 #include <vector>
21 
22 namespace OHOS {
23 namespace Developtools {
24 namespace HiPerf {
25 namespace HiperfClient {
26 const std::string TempBinPath = "/data/local/tmp/";
27 const std::string ReplyOK = "OK\n";
28 const std::string ReplyFAIL = "FAIL\n";
29 const std::string ReplyStart = "START\n";
30 const std::string ReplyOutput = "OUTPUT\n";
31 const std::string ReplyOutputCheck = "OUTPUT_CHECK\n";
32 const std::string ReplyStop = "STOP\n";
33 const std::string ReplyPause = "PAUSE\n";
34 const std::string ReplyResume = "RESUME\n";
35 const std::string ReplyCheck = "CHECK\n";
36 #define HIPERF_EXIT_CODE 0
37 
38 class RecordOption {
39 public:
40     /**
41      * Set output file name, default is perf.data
42      */
SetOutputFilename(const std::string & outputFilename)43     void SetOutputFilename(const std::string &outputFilename)
44     {
45         outputFileName_ = outputFilename;
46     }
47     /**
48      * Get output file name
49      */
GetOutputFileName()50     const std::string GetOutputFileName() const
51     {
52         return outputFileName_;
53     }
54 
55     /**
56      * Get the default events for select.
57      */
GetSelectEvents()58     const std::vector<std::string> &GetSelectEvents() const
59     {
60         return selectEvents_;
61     }
62 
63     /**
64      * Collect system-wide information for measures all processes/threads
65      * default is disable.
66      */
67     void SetTargetSystemWide(bool enable);
68     /**
69      * Compress record data. default is disable.
70      */
71     void SetCompressData(bool enable);
72     /**
73      * Specify cpu ID, cpu ID shoule be 0,1,2...
74      */
75     void SetSelectCpus(const std::vector<int> &cpus);
76     /**
77      * Stop in <timeStopSec> seconds. default is 10000 seconds
78      */
79     void SetTimeStopSec(int timeStopSec);
80     /**
81      * Set event sampling frequency. default is 4000 samples every second.
82      */
83     void SetFrequency(int frequency);
84     /**
85      * Set event sampling period for tracepoint events.
86      * recording one sample when <period> events happen.
87      * default is 1
88      */
89     void SetPeriod(int period);
90     /**
91      * Customize the name of the event that needs to be sampled.
92      */
93     void SetSelectEvents(const std::vector<std::string> &selectEvents);
94     /**
95      * Customize the name of the event that needs to be grouped.
96      * the function is added on the basis of the function of the SetSelectEvents().
97      */
98     void SetSelectGroups(const std::vector<std::string> &selectGroups);
99     /**
100      * Set to don't tracing child processes. default is disable
101      */
102     void SetNoInherit(bool enable);
103     /**
104      * Set the limit process id of the collection target.
105      * Conflicts with the SetTargetSystemWide(true).
106      */
107     void SetSelectPids(const std::vector<pid_t> &selectPids);
108     /**
109      * Set default sampling parameters with specifying the select duration.
110      * default is 10 seconds.
111      */
112     void SetCallStackSamplingConfigs(int duration);
113     /**
114      * Set the limit thread id of the collection target.
115      * Conflicts with the SetTargetSystemWide(true).
116      */
117     void SetSelectTids(const std::vector<pid_t> &selectTids);
118     /**
119      * Set don’t record events issued by hiperf itself.
120      */
121     void SetExcludePerf(bool excludePerf);
122     /**
123      * Set the max percent of cpu time used for recording.
124      * percent is in range [1-100], default is 25
125      */
126     void SetCpuPercent(int cpuPercent);
127     /**
128      * Set tracing when threads are scheduled off cpu, default is disable
129      */
130     void SetOffCPU(bool offCPU);
131     /**
132      * Set call-graph (stack chain/backtrace) recording, Default is 'fp'.
133      * as the method to collect the information used to show the call graphs.
134      * the value can be:
135      *  fp: frame pointer
136      *  dwarf: DWARF's CFI - Call Frame Information
137      *      'dwarf,###' set sample stack size, size should be in 8~65528 and 8 byte aligned.
138      */
139     void SetCallGraph(const std::string &sampleTypes);
140     /**
141      * Set to unwind after recording.
142      * If '-g dwarf' used, stack will be unwind while recording by default
143      */
144     void SetDelayUnwind(bool delayUnwind);
145     /**
146      * Set to disable unwinding.
147      * If '-g dwarf' used, stack will be unwind while recording  by default
148      */
149     void SetDisableUnwind(bool disableUnwind);
150     /**
151      * Set callstack don't merged.
152      * If '-g dwarf' is used, to break the 64k stack limit, callstack is merged by default
153      */
154     void SetDisableCallstackMerge(bool disableCallstackMerge);
155     /**
156      * Set directory to look for symbol files, used for unwinding.
157      */
158     void SetSymbolDir(const std::string &symbolDir_);
159     /**
160      * Set to stop recording after <SIZE> bytes of records. Default is unlimited
161      * format like: SIZE[K|M|G]
162      */
163     void SetDataLimit(const std::string &limit);
164     /**
165      * Set a OHOS app name, collect profile info for this app, the app must be debuggable.
166      */
167     void SetAppPackage(const std::string &appPackage);
168     /**
169      * Set the clock id to use for the various time fields in the perf_event_type records.
170      */
171     void SetClockId(const std::string &clockId);
172     /**
173      * Set to take branch stack sampling, filter can be
174      *  any: any type of branch
175      *  any_call: any function call or system call
176      *  any_ret: any function return or system call return
177      *  ind_call: any indirect branch
178      *  call: direct calls, including far (to/from kernel) calls
179      *  u: only when the branch target is at the user level
180      *  k: only when the branch target is in the kernel\n"
181      */
182     void SetVecBranchSampleTypes(const std::vector<std::string> &vecBranchSampleTypes);
183     /**
184      * Set the size of the buffer used to receiving sample data from kernel,
185      * must be a power of two. If not set,  a value <=1024 will be used.
186      */
187     void SetMmapPages(int mmapPages);
188     /**
189      * Set to report with callstack after recording, default is disable
190      */
191     void SetReport(bool report);
192     /**
193      * Set the limit processes that do not need to be recorded,
194      * must be used with the SetTargetSystemWide(true).
195      */
196     void SetExcludeProcess(const std::vector<std::string>& excludeProcess);
197     /**
198      * Set record mode of collect data of the previous period, default is disable
199      */
200     void SetBackTrack(bool backtrack);
201     /**
202      * Set the time of collect data of the previous period, default is 10 seconds.
203      * Must be used with the SetBackTrack(true).
204      */
205     void SetBackTrackSec(int backTracesec);
206 
207     /**
208      * Get the string vector of all options.
209      */
GetOptionVecString()210     const std::vector<std::string> &GetOptionVecString() const
211     {
212         return args_;
213     }
214 
215     /**
216      * Get TimeSpec attribute
217      */
IsTimeSpecified()218     bool IsTimeSpecified() const
219     {
220         return timeSpec_;
221     }
222 private:
223     bool timeSpec_ = false;
224     std::vector<std::string> args_ = {};
225     std::vector<std::string> selectEvents_ = {"hw-cpu-cycles:u"};
226     std::string outputFileName_ = "";
227 
228     void SetOption(const std::string &name, bool enable);
229     void SetOption(const std::string &name, int value);
230     void SetOption(const std::string &name, const std::vector<int> &vInt);
231     void SetOption(const std::string &name, const std::string &str);
232     void SetOption(const std::string &name, const std::vector<std::string> &vStr);
233 };
234 
235 class Client {
236 public:
237     /**
238      * Set output dir and constuct
239      */
240     explicit Client(const std::string &outputDir = TempBinPath);
241     ~Client();
242     /**
243      * Start record with default options
244      */
245     bool Start();
246     /**
247      * Start record with options of string vector
248      */
249     bool Start(const std::vector<std::string> &args, bool immediately = true);
250     /**
251      * Start record with options of RecordOption
252      */
253     bool Start(const RecordOption &option);
254     /**
255      * Start record synchronizely with specified time
256      */
257     bool RunHiperfCmdSync(const RecordOption &option);
258     /**
259      * prepare record with options of RecordOption
260      */
261     bool PrePare(const RecordOption &option);
262     /**
263      * Start recording after prepare
264      */
265     bool StartRun();
266     /**
267      * Pause recording
268      */
269     bool Pause();
270     /**
271      * Resume recording
272      */
273     bool Resume();
274     /**
275      * Output recording
276      */
277     bool Output();
278     /**
279      * Stop recording
280      */
281     bool Stop();
282     /**
283      * Check the client is ready
284      */
285     bool IsReady();
286     /**
287      * Set the output dir
288      */
289     bool Setup(std::string outputDir);
290 
291     /**
292      * Get the output dir
293      */
GetOutputDir()294     const std::string &GetOutputDir() const
295     {
296         return outputDir_;
297     }
298     /**
299      * Get the command path
300      */
GetCommandPath()301     const std::string &GetCommandPath() const
302     {
303         return executeCommandPath_;
304     }
305     /**
306      * Get the the fullpath of output file
307      */
GetOutputPerfDataPath()308     const std::string GetOutputPerfDataPath() const
309     {
310         return outputDir_ + outputFileName_;
311     }
312 
313     /**
314      * Child run execv cmd
315      */
316     void ChildRunExecv(std::vector<std::string> &cmd);
317     /**
318      * Prepare execv cmd
319      */
320     void PrepareExecCmd(std::vector<std::string> &cmd);
321     /**
322      * Parent wait for child exit
323      */
324     bool ParentWait(pid_t &wpid, pid_t pid, int &childStatus);
325     void SetDebugMode();
326     void SetDebugMuchMode();
327     void EnableHilog();
328     void KillChild();
329 private:
330     static constexpr int64_t HIPERF_TIMEOUT_MILLISECOND = 4000;
331 
332     bool WaitCommandReply(std::chrono::milliseconds = std::chrono::milliseconds(HIPERF_TIMEOUT_MILLISECOND));
333     bool SendCommandAndWait(const std::string &cmd);
334     void GetExecCmd(std::vector<std::string> &cmd, int pipeIn, int pipeOut,
335                     const std::vector<std::string> &args);
336 
337     void GetExecCmd(std::vector<std::string> &cmd,
338                     const std::vector<std::string> &args);
339     std::string outputDir_ = "";
340     std::string outputFileName_ = "";
341     std::string executeCommandPath_ = "";
342     bool ready_ = false;
343     pid_t myPid_ = -1;
344     bool debug_ = false;
345     bool debugMuch_ = false;
346     bool hilog_ = false;
347 
348     int clientToServerFd_ = -1;
349     int serverToClientFd_ = -1;
350     pid_t hperfPid_ = -1;
351     pid_t hperfPrePid_ = -1; // hiperf pid for prepare mode
352 };
353 } // namespace HiperfClient
354 } // namespace HiPerf
355 } // namespace Developtools
356 } // namespace OHOS
357 #endif // HIPERF_CLIENT_H_
358