| 1 | |
| 2 | #define _GNU_SOURCE
|
| 3 | #include <inttypes.h>
|
| 4 | #include <sched.h>
|
| 5 | #include <stdio.h>
|
| 6 | #include <stdarg.h>
|
| 7 | #include <unistd.h>
|
| 8 | #include <stdlib.h>
|
| 9 | #include <linux/perf_event.h>
|
| 10 | #include <linux/limits.h>
|
| 11 | #include <sys/types.h>
|
| 12 | #include <sys/wait.h>
|
| 13 | #include <sys/prctl.h>
|
| 14 | #include <perf/cpumap.h>
|
| 15 | #include <perf/threadmap.h>
|
| 16 | #include <perf/evlist.h>
|
| 17 | #include <perf/evsel.h>
|
| 18 | #include <perf/mmap.h>
|
| 19 | #include <perf/event.h>
|
| 20 | #include <internal/tests.h>
|
| 21 | #include <api/fs/fs.h>
|
| 22 | #include "tests.h"
|
| 23 | #include <internal/evsel.h>
|
| 24 |
|
| 25 | #define EVENT_NUM 15
|
| 26 | #define WAIT_COUNT 100000000UL
|
| 27 |
|
| 28 | static int libperf_print(enum libperf_print_level level,
|
| 29 | const char *fmt, va_list ap)
|
| 30 | {
|
| 31 | return vfprintf(stderr, fmt, ap);
|
| 32 | }
|
| 33 |
|
| 34 | static int test_stat_cpu(void)
|
| 35 | {
|
| 36 | struct perf_cpu_map *cpus;
|
| 37 | struct perf_evlist *evlist;
|
| 38 | struct perf_evsel *evsel, *leader;
|
| 39 | struct perf_event_attr attr1 = {
|
| 40 | .type = PERF_TYPE_SOFTWARE,
|
| 41 | .config = PERF_COUNT_SW_CPU_CLOCK,
|
| 42 | };
|
| 43 | struct perf_event_attr attr2 = {
|
| 44 | .type = PERF_TYPE_SOFTWARE,
|
| 45 | .config = PERF_COUNT_SW_TASK_CLOCK,
|
| 46 | };
|
| 47 | int err, idx;
|
| 48 |
|
| 49 | cpus = perf_cpu_map__new_online_cpus();
|
| 50 | __T("failed to create cpus", cpus);
|
| 51 |
|
| 52 | evlist = perf_evlist__new();
|
| 53 | __T("failed to create evlist", evlist);
|
| 54 |
|
| 55 | evsel = leader = perf_evsel__new(&attr1);
|
| 56 | __T("failed to create evsel1", evsel);
|
| 57 |
|
| 58 | perf_evlist__add(evlist, evsel);
|
| 59 |
|
| 60 | evsel = perf_evsel__new(&attr2);
|
| 61 | __T("failed to create evsel2", evsel);
|
| 62 |
|
| 63 | perf_evlist__add(evlist, evsel);
|
| 64 |
|
| 65 | perf_evlist__set_leader(evlist);
|
| 66 | __T("failed to set leader", leader->leader == leader);
|
| 67 | __T("failed to set leader", evsel->leader == leader);
|
| 68 |
|
| 69 | perf_evlist__set_maps(evlist, cpus, NULL);
|
| 70 |
|
| 71 | err = perf_evlist__open(evlist);
|
| 72 | __T("failed to open evlist", err == 0);
|
| 73 |
|
| 74 | perf_evlist__for_each_evsel(evlist, evsel) {
|
| 75 | cpus = perf_evsel__cpus(evsel);
|
| 76 |
|
| 77 | for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
|
| 78 | struct perf_counts_values counts = { .val = 0 };
|
| 79 |
|
| 80 | perf_evsel__read(evsel, idx, 0, &counts);
|
| 81 | __T("failed to read value for evsel", counts.val != 0);
|
| 82 | }
|
| 83 | }
|
| 84 |
|
| 85 | perf_evlist__close(evlist);
|
| 86 | perf_evlist__delete(evlist);
|
| 87 |
|
| 88 | perf_cpu_map__put(cpus);
|
| 89 | return 0;
|
| 90 | }
|
| 91 |
|
| 92 | static int test_stat_thread(void)
|
| 93 | {
|
| 94 | struct perf_counts_values counts = { .val = 0 };
|
| 95 | struct perf_thread_map *threads;
|
| 96 | struct perf_evlist *evlist;
|
| 97 | struct perf_evsel *evsel, *leader;
|
| 98 | struct perf_event_attr attr1 = {
|
| 99 | .type = PERF_TYPE_SOFTWARE,
|
| 100 | .config = PERF_COUNT_SW_CPU_CLOCK,
|
| 101 | };
|
| 102 | struct perf_event_attr attr2 = {
|
| 103 | .type = PERF_TYPE_SOFTWARE,
|
| 104 | .config = PERF_COUNT_SW_TASK_CLOCK,
|
| 105 | };
|
| 106 | int err;
|
| 107 |
|
| 108 | threads = perf_thread_map__new_dummy();
|
| 109 | __T("failed to create threads", threads);
|
| 110 |
|
| 111 | perf_thread_map__set_pid(threads, 0, 0);
|
| 112 |
|
| 113 | evlist = perf_evlist__new();
|
| 114 | __T("failed to create evlist", evlist);
|
| 115 |
|
| 116 | evsel = leader = perf_evsel__new(&attr1);
|
| 117 | __T("failed to create evsel1", evsel);
|
| 118 |
|
| 119 | perf_evlist__add(evlist, evsel);
|
| 120 |
|
| 121 | evsel = perf_evsel__new(&attr2);
|
| 122 | __T("failed to create evsel2", evsel);
|
| 123 |
|
| 124 | perf_evlist__add(evlist, evsel);
|
| 125 |
|
| 126 | perf_evlist__set_leader(evlist);
|
| 127 | __T("failed to set leader", leader->leader == leader);
|
| 128 | __T("failed to set leader", evsel->leader == leader);
|
| 129 |
|
| 130 | perf_evlist__set_maps(evlist, NULL, threads);
|
| 131 |
|
| 132 | err = perf_evlist__open(evlist);
|
| 133 | __T("failed to open evlist", err == 0);
|
| 134 |
|
| 135 | perf_evlist__for_each_evsel(evlist, evsel) {
|
| 136 | perf_evsel__read(evsel, 0, 0, &counts);
|
| 137 | __T("failed to read value for evsel", counts.val != 0);
|
| 138 | }
|
| 139 |
|
| 140 | perf_evlist__close(evlist);
|
| 141 | perf_evlist__delete(evlist);
|
| 142 |
|
| 143 | perf_thread_map__put(threads);
|
| 144 | return 0;
|
| 145 | }
|
| 146 |
|
| 147 | static int test_stat_thread_enable(void)
|
| 148 | {
|
| 149 | struct perf_counts_values counts = { .val = 0 };
|
| 150 | struct perf_thread_map *threads;
|
| 151 | struct perf_evlist *evlist;
|
| 152 | struct perf_evsel *evsel, *leader;
|
| 153 | struct perf_event_attr attr1 = {
|
| 154 | .type = PERF_TYPE_SOFTWARE,
|
| 155 | .config = PERF_COUNT_SW_CPU_CLOCK,
|
| 156 | .disabled = 1,
|
| 157 | };
|
| 158 | struct perf_event_attr attr2 = {
|
| 159 | .type = PERF_TYPE_SOFTWARE,
|
| 160 | .config = PERF_COUNT_SW_TASK_CLOCK,
|
| 161 | .disabled = 1,
|
| 162 | };
|
| 163 | int err;
|
| 164 |
|
| 165 | threads = perf_thread_map__new_dummy();
|
| 166 | __T("failed to create threads", threads);
|
| 167 |
|
| 168 | perf_thread_map__set_pid(threads, 0, 0);
|
| 169 |
|
| 170 | evlist = perf_evlist__new();
|
| 171 | __T("failed to create evlist", evlist);
|
| 172 |
|
| 173 | evsel = leader = perf_evsel__new(&attr1);
|
| 174 | __T("failed to create evsel1", evsel);
|
| 175 |
|
| 176 | perf_evlist__add(evlist, evsel);
|
| 177 |
|
| 178 | evsel = perf_evsel__new(&attr2);
|
| 179 | __T("failed to create evsel2", evsel);
|
| 180 |
|
| 181 | perf_evlist__add(evlist, evsel);
|
| 182 |
|
| 183 | perf_evlist__set_leader(evlist);
|
| 184 | __T("failed to set leader", leader->leader == leader);
|
| 185 | __T("failed to set leader", evsel->leader == leader);
|
| 186 |
|
| 187 | perf_evlist__set_maps(evlist, NULL, threads);
|
| 188 |
|
| 189 | err = perf_evlist__open(evlist);
|
| 190 | __T("failed to open evlist", err == 0);
|
| 191 |
|
| 192 | perf_evlist__for_each_evsel(evlist, evsel) {
|
| 193 | perf_evsel__read(evsel, 0, 0, &counts);
|
| 194 | __T("failed to read value for evsel", counts.val == 0);
|
| 195 | }
|
| 196 |
|
| 197 | perf_evlist__enable(evlist);
|
| 198 |
|
| 199 | perf_evlist__for_each_evsel(evlist, evsel) {
|
| 200 | perf_evsel__read(evsel, 0, 0, &counts);
|
| 201 | __T("failed to read value for evsel", counts.val != 0);
|
| 202 | }
|
| 203 |
|
| 204 | perf_evlist__disable(evlist);
|
| 205 |
|
| 206 | perf_evlist__close(evlist);
|
| 207 | perf_evlist__delete(evlist);
|
| 208 |
|
| 209 | perf_thread_map__put(threads);
|
| 210 | return 0;
|
| 211 | }
|
| 212 |
|
| 213 | static int test_mmap_thread(void)
|
| 214 | {
|
| 215 | struct perf_evlist *evlist;
|
| 216 | struct perf_evsel *evsel;
|
| 217 | struct perf_mmap *map;
|
| 218 | struct perf_cpu_map *cpus;
|
| 219 | struct perf_thread_map *threads;
|
| 220 | struct perf_event_attr attr = {
|
| 221 | .type = PERF_TYPE_TRACEPOINT,
|
| 222 | .sample_period = 1,
|
| 223 | .wakeup_watermark = 1,
|
| 224 | .disabled = 1,
|
| 225 | };
|
| 226 | char path[PATH_MAX];
|
| 227 | int id, err, pid, go_pipe[2];
|
| 228 | union perf_event *event;
|
| 229 | int count = 0;
|
| 230 |
|
| 231 | snprintf(path, PATH_MAX, "%s/kernel/debug/tracing/events/syscalls/sys_enter_prctl/id",
|
| 232 | sysfs__mountpoint());
|
| 233 |
|
| 234 | if (filename__read_int(path, &id)) {
|
| 235 | tests_failed++;
|
| 236 | fprintf(stderr, "error: failed to get tracepoint id: %s\n", path);
|
| 237 | return -1;
|
| 238 | }
|
| 239 |
|
| 240 | attr.config = id;
|
| 241 |
|
| 242 | err = pipe(go_pipe);
|
| 243 | __T("failed to create pipe", err == 0);
|
| 244 |
|
| 245 | fflush(NULL);
|
| 246 |
|
| 247 | pid = fork();
|
| 248 | if (!pid) {
|
| 249 | int i;
|
| 250 | char bf;
|
| 251 |
|
| 252 | read(go_pipe[0], &bf, 1);
|
| 253 |
|
| 254 |
|
| 255 | for (i = 0; i < 100; i++)
|
| 256 | prctl(0, 0, 0, 0, 0);
|
| 257 |
|
| 258 | exit(0);
|
| 259 | }
|
| 260 |
|
| 261 | threads = perf_thread_map__new_dummy();
|
| 262 | __T("failed to create threads", threads);
|
| 263 |
|
| 264 | cpus = perf_cpu_map__new_any_cpu();
|
| 265 | __T("failed to create cpus", cpus);
|
| 266 |
|
| 267 | perf_thread_map__set_pid(threads, 0, pid);
|
| 268 |
|
| 269 | evlist = perf_evlist__new();
|
| 270 | __T("failed to create evlist", evlist);
|
| 271 |
|
| 272 | evsel = perf_evsel__new(&attr);
|
| 273 | __T("failed to create evsel1", evsel);
|
| 274 | __T("failed to set leader", evsel->leader == evsel);
|
| 275 |
|
| 276 | perf_evlist__add(evlist, evsel);
|
| 277 |
|
| 278 | perf_evlist__set_maps(evlist, cpus, threads);
|
| 279 |
|
| 280 | err = perf_evlist__open(evlist);
|
| 281 | __T("failed to open evlist", err == 0);
|
| 282 |
|
| 283 | err = perf_evlist__mmap(evlist, 4);
|
| 284 | __T("failed to mmap evlist", err == 0);
|
| 285 |
|
| 286 | perf_evlist__enable(evlist);
|
| 287 |
|
| 288 |
|
| 289 | write(go_pipe[1], "A", 1);
|
| 290 | waitpid(pid, NULL, 0);
|
| 291 |
|
| 292 | |
| 293 | * There's no need to call perf_evlist__disable,
|
| 294 | * monitored process is dead now.
|
| 295 |
|
| 296 |
|
| 297 | perf_evlist__for_each_mmap(evlist, map, false) {
|
| 298 | if (perf_mmap__read_init(map) < 0)
|
| 299 | continue;
|
| 300 |
|
| 301 | while ((event = perf_mmap__read_event(map)) != NULL) {
|
| 302 | count++;
|
| 303 | perf_mmap__consume(map);
|
| 304 | }
|
| 305 |
|
| 306 | perf_mmap__read_done(map);
|
| 307 | }
|
| 308 |
|
| 309 |
|
| 310 | perf_evlist__delete(evlist);
|
| 311 |
|
| 312 | perf_thread_map__put(threads);
|
| 313 | perf_cpu_map__put(cpus);
|
| 314 |
|
| 315 | |
| 316 | * The generated prctl calls should match the
|
| 317 | * number of events in the buffer.
|
| 318 |
|
| 319 | __T("failed count", count == 100);
|
| 320 |
|
| 321 | return 0;
|
| 322 | }
|
| 323 |
|
| 324 | static int test_mmap_cpus(void)
|
| 325 | {
|
| 326 | struct perf_evlist *evlist;
|
| 327 | struct perf_evsel *evsel;
|
| 328 | struct perf_mmap *map;
|
| 329 | struct perf_cpu_map *cpus;
|
| 330 | struct perf_event_attr attr = {
|
| 331 | .type = PERF_TYPE_TRACEPOINT,
|
| 332 | .sample_period = 1,
|
| 333 | .wakeup_watermark = 1,
|
| 334 | .disabled = 1,
|
| 335 | };
|
| 336 | cpu_set_t saved_mask;
|
| 337 | char path[PATH_MAX];
|
| 338 | int id, err, tmp;
|
| 339 | struct perf_cpu cpu;
|
| 340 | union perf_event *event;
|
| 341 | int count = 0;
|
| 342 |
|
| 343 | snprintf(path, PATH_MAX, "%s/kernel/debug/tracing/events/syscalls/sys_enter_prctl/id",
|
| 344 | sysfs__mountpoint());
|
| 345 |
|
| 346 | if (filename__read_int(path, &id)) {
|
| 347 | fprintf(stderr, "error: failed to get tracepoint id: %s\n", path);
|
| 348 | return -1;
|
| 349 | }
|
| 350 |
|
| 351 | attr.config = id;
|
| 352 |
|
| 353 | cpus = perf_cpu_map__new_online_cpus();
|
| 354 | __T("failed to create cpus", cpus);
|
| 355 |
|
| 356 | evlist = perf_evlist__new();
|
| 357 | __T("failed to create evlist", evlist);
|
| 358 |
|
| 359 | evsel = perf_evsel__new(&attr);
|
| 360 | __T("failed to create evsel1", evsel);
|
| 361 | __T("failed to set leader", evsel->leader == evsel);
|
| 362 |
|
| 363 | perf_evlist__add(evlist, evsel);
|
| 364 |
|
| 365 | perf_evlist__set_maps(evlist, cpus, NULL);
|
| 366 |
|
| 367 | err = perf_evlist__open(evlist);
|
| 368 | __T("failed to open evlist", err == 0);
|
| 369 |
|
| 370 | err = perf_evlist__mmap(evlist, 4);
|
| 371 | __T("failed to mmap evlist", err == 0);
|
| 372 |
|
| 373 | perf_evlist__enable(evlist);
|
| 374 |
|
| 375 | err = sched_getaffinity(0, sizeof(saved_mask), &saved_mask);
|
| 376 | __T("sched_getaffinity failed", err == 0);
|
| 377 |
|
| 378 | perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
|
| 379 | cpu_set_t mask;
|
| 380 |
|
| 381 | CPU_ZERO(&mask);
|
| 382 | CPU_SET(cpu.cpu, &mask);
|
| 383 |
|
| 384 | err = sched_setaffinity(0, sizeof(mask), &mask);
|
| 385 | __T("sched_setaffinity failed", err == 0);
|
| 386 |
|
| 387 | prctl(0, 0, 0, 0, 0);
|
| 388 | }
|
| 389 |
|
| 390 | err = sched_setaffinity(0, sizeof(saved_mask), &saved_mask);
|
| 391 | __T("sched_setaffinity failed", err == 0);
|
| 392 |
|
| 393 | perf_evlist__disable(evlist);
|
| 394 |
|
| 395 | perf_evlist__for_each_mmap(evlist, map, false) {
|
| 396 | if (perf_mmap__read_init(map) < 0)
|
| 397 | continue;
|
| 398 |
|
| 399 | while ((event = perf_mmap__read_event(map)) != NULL) {
|
| 400 | count++;
|
| 401 | perf_mmap__consume(map);
|
| 402 | }
|
| 403 |
|
| 404 | perf_mmap__read_done(map);
|
| 405 | }
|
| 406 |
|
| 407 |
|
| 408 | perf_evlist__delete(evlist);
|
| 409 |
|
| 410 | |
| 411 | * The generated prctl events should match the
|
| 412 | * number of cpus or be bigger (we are system-wide).
|
| 413 |
|
| 414 | __T("failed count", count >= perf_cpu_map__nr(cpus));
|
| 415 |
|
| 416 | perf_cpu_map__put(cpus);
|
| 417 |
|
| 418 | return 0;
|
| 419 | }
|
| 420 |
|
| 421 | static double display_error(long long average,
|
| 422 | long long high,
|
| 423 | long long low,
|
| 424 | long long expected)
|
| 425 | {
|
| 426 | double error;
|
| 427 |
|
| 428 | error = (((double)average - expected) / expected) * 100.0;
|
| 429 |
|
| 430 | __T_VERBOSE(" Expected: %lld\n", expected);
|
| 431 | __T_VERBOSE(" High: %lld Low: %lld Average: %lld\n",
|
| 432 | high, low, average);
|
| 433 |
|
| 434 | __T_VERBOSE(" Average Error = %.2f%%\n", error);
|
| 435 |
|
| 436 | return error;
|
| 437 | }
|
| 438 |
|
| 439 | static int test_stat_multiplexing(void)
|
| 440 | {
|
| 441 | struct perf_counts_values expected_counts = { .val = 0 };
|
| 442 | struct perf_counts_values counts[EVENT_NUM] = {{ .val = 0 },};
|
| 443 | struct perf_thread_map *threads;
|
| 444 | struct perf_evlist *evlist;
|
| 445 | struct perf_evsel *evsel;
|
| 446 | struct perf_event_attr attr = {
|
| 447 | .type = PERF_TYPE_HARDWARE,
|
| 448 | .config = PERF_COUNT_HW_INSTRUCTIONS,
|
| 449 | .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
|
| 450 | PERF_FORMAT_TOTAL_TIME_RUNNING,
|
| 451 | .disabled = 1,
|
| 452 | };
|
| 453 | int err, i, nonzero = 0;
|
| 454 | unsigned long count;
|
| 455 | long long max = 0, min = 0, avg = 0;
|
| 456 | double error = 0.0;
|
| 457 | s8 scaled = 0;
|
| 458 |
|
| 459 |
|
| 460 | threads = perf_thread_map__new_dummy();
|
| 461 | __T("failed to create threads", threads);
|
| 462 |
|
| 463 | perf_thread_map__set_pid(threads, 0, 0);
|
| 464 |
|
| 465 | evsel = perf_evsel__new(&attr);
|
| 466 | __T("failed to create evsel", evsel);
|
| 467 |
|
| 468 | err = perf_evsel__open(evsel, NULL, threads);
|
| 469 | __T("failed to open evsel", err == 0);
|
| 470 |
|
| 471 | err = perf_evsel__enable(evsel);
|
| 472 | __T("failed to enable evsel", err == 0);
|
| 473 |
|
| 474 |
|
| 475 | count = WAIT_COUNT;
|
| 476 | while (count--)
|
| 477 | ;
|
| 478 |
|
| 479 | perf_evsel__read(evsel, 0, 0, &expected_counts);
|
| 480 | __T("failed to read value for evsel", expected_counts.val != 0);
|
| 481 | __T("failed to read non-multiplexing event count",
|
| 482 | expected_counts.ena == expected_counts.run);
|
| 483 |
|
| 484 | err = perf_evsel__disable(evsel);
|
| 485 | __T("failed to enable evsel", err == 0);
|
| 486 |
|
| 487 | perf_evsel__close(evsel);
|
| 488 | perf_evsel__delete(evsel);
|
| 489 |
|
| 490 | perf_thread_map__put(threads);
|
| 491 |
|
| 492 |
|
| 493 | threads = perf_thread_map__new_dummy();
|
| 494 | __T("failed to create threads", threads);
|
| 495 |
|
| 496 | perf_thread_map__set_pid(threads, 0, 0);
|
| 497 |
|
| 498 | evlist = perf_evlist__new();
|
| 499 | __T("failed to create evlist", evlist);
|
| 500 |
|
| 501 | for (i = 0; i < EVENT_NUM; i++) {
|
| 502 | evsel = perf_evsel__new(&attr);
|
| 503 | __T("failed to create evsel", evsel);
|
| 504 |
|
| 505 | perf_evlist__add(evlist, evsel);
|
| 506 | }
|
| 507 | perf_evlist__set_maps(evlist, NULL, threads);
|
| 508 |
|
| 509 | err = perf_evlist__open(evlist);
|
| 510 | __T("failed to open evlist", err == 0);
|
| 511 |
|
| 512 | perf_evlist__enable(evlist);
|
| 513 |
|
| 514 |
|
| 515 | count = WAIT_COUNT;
|
| 516 | while (count--)
|
| 517 | ;
|
| 518 |
|
| 519 | i = 0;
|
| 520 | perf_evlist__for_each_evsel(evlist, evsel) {
|
| 521 | perf_evsel__read(evsel, 0, 0, &counts[i]);
|
| 522 | __T("failed to read value for evsel", counts[i].val != 0);
|
| 523 | i++;
|
| 524 | }
|
| 525 |
|
| 526 | perf_evlist__disable(evlist);
|
| 527 |
|
| 528 | min = counts[0].val;
|
| 529 | for (i = 0; i < EVENT_NUM; i++) {
|
| 530 | __T_VERBOSE("Event %2d -- Raw count = %" PRIu64 ", run = %" PRIu64 ", enable = %" PRIu64 "\n",
|
| 531 | i, counts[i].val, counts[i].run, counts[i].ena);
|
| 532 |
|
| 533 | perf_counts_values__scale(&counts[i], true, &scaled);
|
| 534 | if (scaled == 1) {
|
| 535 | __T_VERBOSE("\t Scaled count = %" PRIu64 " (%.2lf%%, %" PRIu64 "/%" PRIu64 ")\n",
|
| 536 | counts[i].val,
|
| 537 | (double)counts[i].run / (double)counts[i].ena * 100.0,
|
| 538 | counts[i].run, counts[i].ena);
|
| 539 | } else if (scaled == -1) {
|
| 540 | __T_VERBOSE("\t Not Running\n");
|
| 541 | } else {
|
| 542 | __T_VERBOSE("\t Not Scaling\n");
|
| 543 | }
|
| 544 |
|
| 545 | if (counts[i].val > max)
|
| 546 | max = counts[i].val;
|
| 547 |
|
| 548 | if (counts[i].val < min)
|
| 549 | min = counts[i].val;
|
| 550 |
|
| 551 | avg += counts[i].val;
|
| 552 |
|
| 553 | if (counts[i].val != 0)
|
| 554 | nonzero++;
|
| 555 | }
|
| 556 |
|
| 557 | if (nonzero != 0)
|
| 558 | avg = avg / nonzero;
|
| 559 | else
|
| 560 | avg = 0;
|
| 561 |
|
| 562 | error = display_error(avg, max, min, expected_counts.val);
|
| 563 |
|
| 564 | __T("Error out of range!", ((error <= 1.0) && (error >= -1.0)));
|
| 565 |
|
| 566 | perf_evlist__close(evlist);
|
| 567 | perf_evlist__delete(evlist);
|
| 568 |
|
| 569 | perf_thread_map__put(threads);
|
| 570 |
|
| 571 | return 0;
|
| 572 | }
|
| 573 |
|
| 574 | int test_evlist(int argc, char **argv)
|
| 575 | {
|
| 576 | __T_START;
|
| 577 |
|
| 578 | libperf_init(libperf_print);
|
| 579 |
|
| 580 | test_stat_cpu();
|
| 581 | test_stat_thread();
|
| 582 | test_stat_thread_enable();
|
| 583 | test_mmap_thread();
|
| 584 | test_mmap_cpus();
|
| 585 | test_stat_multiplexing();
|
| 586 |
|
| 587 | __T_END;
|
| 588 | return tests_failed == 0 ? 0 : -1;
|
| 589 | }
|