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