• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <unistd.h>
33 #include <securec.h>
34 #include <sys/wait.h>
35 #include "perf.h"
36 #include "option.h"
37 #include "perf_stat.h"
38 
39 static PerfConfigAttr g_statAttr;
40 
GetEvents(const char * argv)41 static inline int GetEvents(const char *argv)
42 {
43     return ParseEvents(argv, &g_statAttr.eventsCfg, &g_statAttr.eventsCfg.eventsNr);
44 }
45 
GetTids(const char * argv)46 static inline int GetTids(const char *argv)
47 {
48     return ParseIds(argv, (int *)g_statAttr.taskIds, &g_statAttr.taskIdsNr);
49 }
50 
GetPids(const char * argv)51 static inline int GetPids(const char *argv)
52 {
53     return ParseIds(argv, (int *)g_statAttr.processIds, &g_statAttr.processIdsNr);
54 }
55 
56 static PerfOption g_statOpts[] = {
57     OPTION_CALLBACK("-e", GetEvents),
58     OPTION_CALLBACK("-t", GetTids),
59     OPTION_CALLBACK("-P", GetPids),
60     OPTION_UINT("-p", &g_statAttr.eventsCfg.events[0].period),
61     OPTION_UINT("-s", &g_statAttr.sampleType),
62     OPTION_UINT("-d", &g_statAttr.eventsCfg.predivided),
63 };
64 
PerfStatAttrInit(void)65 static int PerfStatAttrInit(void)
66 {
67     PerfConfigAttr attr = {
68         .eventsCfg = {
69 #ifdef LOSCFG_PERF_HW_PMU
70             .type = PERF_EVENT_TYPE_HW,
71             .events = {
72                 [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF},
73                 [1] = {PERF_COUNT_HW_INSTRUCTIONS, 0xFFFFFF00},
74                 [2] = {PERF_COUNT_HW_ICACHE_REFERENCES, 0xFFFF},
75                 [3] = {PERF_COUNT_HW_DCACHE_REFERENCES, 0xFFFF},
76             },
77             .eventsNr = 4, /* 4 events */
78 #elif defined LOSCFG_PERF_TIMED_PMU
79             .type = PERF_EVENT_TYPE_TIMED,
80             .events = {
81                 [0] = {PERF_COUNT_CPU_CLOCK, 100},
82             },
83             .eventsNr = 1, /* 1 event */
84 #elif defined LOSCFG_PERF_SW_PMU
85             .type = PERF_EVENT_TYPE_SW,
86             .events = {
87                 [0] = {PERF_COUNT_SW_TASK_SWITCH, 1},
88                 [1] = {PERF_COUNT_SW_IRQ_RESPONSE, 1},
89                 [2] = {PERF_COUNT_SW_MEM_ALLOC, 1},
90                 [3] = {PERF_COUNT_SW_MUX_PEND, 1},
91             },
92             .eventsNr = 4, /* 4 events */
93 #endif
94             .predivided = 0,
95         },
96         .taskIds = {0},
97         .taskIdsNr = 0,
98         .processIds = {0},
99         .processIdsNr = 0,
100         .needSample = 0,
101         .sampleType = 0,
102     };
103 
104     return memcpy_s(&g_statAttr, sizeof(PerfConfigAttr), &attr, sizeof(PerfConfigAttr)) != EOK ? -1 : 0;
105 }
106 
PerfStat(int fd,int argc,char ** argv)107 void PerfStat(int fd, int argc, char **argv)
108 {
109     int ret;
110     int child;
111     SubCmd cmd = {0};
112 
113     if (argc < 3) { /* perf stat argc is at least 3 */
114         return;
115     }
116 
117     ret = PerfStatAttrInit();
118     if (ret != 0) {
119         printf("perf stat attr init failed\n");
120         return;
121     }
122 
123     ret = ParseOptions(argc - 2, &argv[2], g_statOpts, &cmd); /* parse option and cmd begin at index 2 */
124     if (ret != 0) {
125         printf("parse error\n");
126         return;
127     }
128 
129     ret = PerfConfig(fd, &g_statAttr);
130     if (ret != 0) {
131         printf("perf config failed\n");
132         return;
133     }
134 
135     PerfStart(fd, 0);
136     child = fork();
137     if (child < 0) {
138         printf("fork error\n");
139         goto EXIT;
140     } else if (child == 0) {
141         (void)execve(cmd.path, cmd.params, NULL);
142         exit(0);
143     }
144 
145     (void)waitpid(child, 0, 0);
146 EXIT:
147     PerfStop(fd);
148 }
149 
150