16 int i, cpu = -1, nrcpus = 1024;
20 if (sched_getaffinity(pid,
sizeof(*maskp), maskp) == -1) {
21 if (errno == EINVAL && nrcpus < (1024 << 8)) {
25 perror(
"sched_getaffinity");
29 for (i = 0; i < nrcpus; i++) {
30 if (CPU_ISSET(i, maskp)) {
52 size_t cpu_mask_size =
sizeof(cpu_mask);
56 const char *cmd =
"sleep";
57 const char *argv[] = { cmd,
"1", NULL, };
58 char *bname, *mmap_filename;
60 bool found_cmd_mmap =
false,
61 found_libc_mmap =
false,
62 found_vdso_mmap =
false,
63 found_ld_mmap =
false;
64 int err = -1, errs = 0, i, wakeups = 0;
66 int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, };
73 pr_debug(
"Not enough memory to create evlist\n");
85 pr_debug(
"Not enough memory to create thread/cpu maps\n");
86 goto out_delete_evlist;
97 pr_debug(
"Couldn't run the workload!\n");
98 goto out_delete_evlist;
112 pr_debug(
"sched__get_first_possible_cpu: %s\n",
113 str_error_r(errno, sbuf,
sizeof(sbuf)));
114 goto out_delete_evlist;
122 if (sched_setaffinity(evlist->
workload.
pid, cpu_mask_size, &cpu_mask) < 0) {
124 str_error_r(errno, sbuf,
sizeof(sbuf)));
125 goto out_delete_evlist;
135 str_error_r(errno, sbuf,
sizeof(sbuf)));
136 goto out_delete_evlist;
147 str_error_r(errno, sbuf,
sizeof(sbuf)));
148 goto out_delete_evlist;
163 int before = total_events;
165 for (i = 0; i < evlist->
nr_mmaps; i++) {
169 md = &evlist->
mmap[i];
174 const u32 type =
event->header.type;
178 if (type < PERF_RECORD_MAX)
185 pr_debug(
"Couldn't parse sample\n");
186 goto out_delete_evlist;
194 if (prev_time > sample.
time) {
195 pr_debug(
"%s going backwards in time, prev=%" PRIu64
", curr=%" PRIu64
"\n",
196 name, prev_time, sample.
time);
200 prev_time = sample.
time;
202 if (sample.
cpu != cpu) {
203 pr_debug(
"%s with unexpected cpu, expected %d, got %d\n",
204 name, cpu, sample.
cpu);
209 pr_debug(
"%s with unexpected pid, expected %d, got %d\n",
215 pr_debug(
"%s with unexpected tid, expected %d, got %d\n",
220 if ((type == PERF_RECORD_COMM ||
221 type == PERF_RECORD_MMAP ||
222 type == PERF_RECORD_MMAP2 ||
223 type == PERF_RECORD_FORK ||
224 type == PERF_RECORD_EXIT) &&
226 pr_debug(
"%s with unexpected pid/tid\n", name);
230 if ((type == PERF_RECORD_COMM ||
231 type == PERF_RECORD_MMAP ||
232 type == PERF_RECORD_MMAP2) &&
234 pr_debug(
"%s with different pid/tid!\n", name);
239 case PERF_RECORD_COMM:
240 if (strcmp(event->
comm.
comm, cmd)) {
241 pr_debug(
"%s with unexpected comm!\n", name);
245 case PERF_RECORD_EXIT:
247 case PERF_RECORD_MMAP:
248 mmap_filename =
event->mmap.filename;
250 case PERF_RECORD_MMAP2:
251 mmap_filename =
event->mmap2.filename;
253 bname = strrchr(mmap_filename,
'/');
256 found_cmd_mmap = !strcmp(bname + 1, cmd);
257 if (!found_libc_mmap)
258 found_libc_mmap = !strncmp(bname + 1,
"libc", 4);
260 found_ld_mmap = !strncmp(bname + 1,
"ld", 2);
261 }
else if (!found_vdso_mmap)
262 found_vdso_mmap = !strcmp(mmap_filename,
"[vdso]");
265 case PERF_RECORD_SAMPLE:
269 pr_debug(
"Unexpected perf_event->header.type %d!\n",
284 if (total_events == before &&
false)
289 pr_debug(
"No PERF_RECORD_EXIT event!\n");
295 if (nr_events[PERF_RECORD_COMM] > 1) {
296 pr_debug(
"Excessive number of PERF_RECORD_COMM events!\n");
300 if (nr_events[PERF_RECORD_COMM] == 0) {
301 pr_debug(
"Missing PERF_RECORD_COMM for %s!\n", cmd);
305 if (!found_cmd_mmap) {
306 pr_debug(
"PERF_RECORD_MMAP for %s missing!\n", cmd);
310 if (!found_libc_mmap) {
311 pr_debug(
"PERF_RECORD_MMAP for %s missing!\n",
"libc");
315 if (!found_ld_mmap) {
316 pr_debug(
"PERF_RECORD_MMAP for %s missing!\n",
"ld");
320 if (!found_vdso_mmap) {
321 pr_debug(
"PERF_RECORD_MMAP for %s missing!\n",
"[vdso]");
327 return (err < 0 || errs > 0) ? -1 : 0;
int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, const char *argv[], bool pipe_output, void(*exec_error)(int signo, siginfo_t *info, void *ucontext))
void perf_mmap__consume(struct perf_mmap *map)
struct perf_evlist::@110 workload
int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unused)
int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
struct perf_evlist * perf_evlist__new_default(void)
void perf_evlist__enable(struct perf_evlist *evlist)
void perf_evlist__delete(struct perf_evlist *evlist)
#define perf_evsel__set_sample_bit(evsel, bit)
int perf_evlist__start_workload(struct perf_evlist *evlist)
struct perf_evlist * perf_evlist__new_dummy(void)
int perf_mmap__read_init(struct perf_mmap *map)
int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
#define pr_debug(fmt,...)
int perf_evlist__open(struct perf_evlist *evlist)
int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, struct perf_sample *sample)
void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct callchain_param *callchain)
const char * perf_event__name(unsigned int id)
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages)
void perf_mmap__read_done(struct perf_mmap *map)
static struct perf_evsel * perf_evlist__first(struct perf_evlist *evlist)
union perf_event * perf_mmap__read_event(struct perf_mmap *map)
size_t perf_event__fprintf(union perf_event *event, FILE *fp)
static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)