Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/lib/perf/tests/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 13 kB image not shown  

Quelle  test-evlist.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE // needed for sched.h to get sched_[gs]etaffinity and CPU_(ZERO,SET)
#include <inttypes.h>
#include <sched.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdlib.h>
#include <linux/perf_event.h>
#include <linux/limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <perf/cpumap.h>
#include <perf/threadmap.h>
#include <perf/evlist.h>
#include <perf/evsel.h>
#include <perf/mmap.h>
#include <perf/event.h>
#include <internal/tests.h>
#include <api/fs/fs.h>
#include "tests.h"
#include <internal/evsel.h>

#define EVENT_NUM 15
#define WAIT_COUNT 100000000UL

static int libperf_print(enum libperf_print_level level,
    const char *fmt, va_list ap)
{
 return vfprintf(stderr, fmt, ap);
}

static int test_stat_cpu(void)
{
 struct perf_cpu_map *cpus;
 struct perf_evlist *evlist;
 struct perf_evsel *evsel, *leader;
 struct perf_event_attr attr1 = {
  .type = PERF_TYPE_SOFTWARE,
  .config = PERF_COUNT_SW_CPU_CLOCK,
 };
 struct perf_event_attr attr2 = {
  .type = PERF_TYPE_SOFTWARE,
  .config = PERF_COUNT_SW_TASK_CLOCK,
 };
 int err, idx;

 cpus = perf_cpu_map__new_online_cpus();
 __T("failed to create cpus", cpus);

 evlist = perf_evlist__new();
 __T("failed to create evlist", evlist);

 evsel = leader = perf_evsel__new(&attr1);
 __T("failed to create evsel1", evsel);

 perf_evlist__add(evlist, evsel);

 evsel = perf_evsel__new(&attr2);
 __T("failed to create evsel2", evsel);

 perf_evlist__add(evlist, evsel);

 perf_evlist__set_leader(evlist);
 __T("failed to set leader", leader->leader == leader);
 __T("failed to set leader", evsel->leader  == leader);

 perf_evlist__set_maps(evlist, cpus, NULL);

 err = perf_evlist__open(evlist);
 __T("failed to open evlist", err == 0);

 perf_evlist__for_each_evsel(evlist, evsel) {
  cpus = perf_evsel__cpus(evsel);

  for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
   struct perf_counts_values counts = { .val = 0 };

   perf_evsel__read(evsel, idx, 0, &counts);
   __T("failed to read value for evsel", counts.val != 0);
  }
 }

 perf_evlist__close(evlist);
 perf_evlist__delete(evlist);

 perf_cpu_map__put(cpus);
 return 0;
}

static int test_stat_thread(void)
{
 struct perf_counts_values counts = { .val = 0 };
 struct perf_thread_map *threads;
 struct perf_evlist *evlist;
 struct perf_evsel *evsel, *leader;
 struct perf_event_attr attr1 = {
  .type = PERF_TYPE_SOFTWARE,
  .config = PERF_COUNT_SW_CPU_CLOCK,
 };
 struct perf_event_attr attr2 = {
  .type = PERF_TYPE_SOFTWARE,
  .config = PERF_COUNT_SW_TASK_CLOCK,
 };
 int err;

 threads = perf_thread_map__new_dummy();
 __T("failed to create threads", threads);

 perf_thread_map__set_pid(threads, 0, 0);

 evlist = perf_evlist__new();
 __T("failed to create evlist", evlist);

 evsel = leader = perf_evsel__new(&attr1);
 __T("failed to create evsel1", evsel);

 perf_evlist__add(evlist, evsel);

 evsel = perf_evsel__new(&attr2);
 __T("failed to create evsel2", evsel);

 perf_evlist__add(evlist, evsel);

 perf_evlist__set_leader(evlist);
 __T("failed to set leader", leader->leader == leader);
 __T("failed to set leader", evsel->leader  == leader);

 perf_evlist__set_maps(evlist, NULL, threads);

 err = perf_evlist__open(evlist);
 __T("failed to open evlist", err == 0);

 perf_evlist__for_each_evsel(evlist, evsel) {
  perf_evsel__read(evsel, 0, 0, &counts);
  __T("failed to read value for evsel", counts.val != 0);
 }

 perf_evlist__close(evlist);
 perf_evlist__delete(evlist);

 perf_thread_map__put(threads);
 return 0;
}

static int test_stat_thread_enable(void)
{
 struct perf_counts_values counts = { .val = 0 };
 struct perf_thread_map *threads;
 struct perf_evlist *evlist;
 struct perf_evsel *evsel, *leader;
 struct perf_event_attr attr1 = {
  .type   = PERF_TYPE_SOFTWARE,
  .config   = PERF_COUNT_SW_CPU_CLOCK,
  .disabled = 1,
 };
 struct perf_event_attr attr2 = {
  .type   = PERF_TYPE_SOFTWARE,
  .config   = PERF_COUNT_SW_TASK_CLOCK,
  .disabled = 1,
 };
 int err;

 threads = perf_thread_map__new_dummy();
 __T("failed to create threads", threads);

 perf_thread_map__set_pid(threads, 0, 0);

 evlist = perf_evlist__new();
 __T("failed to create evlist", evlist);

 evsel = leader = perf_evsel__new(&attr1);
 __T("failed to create evsel1", evsel);

 perf_evlist__add(evlist, evsel);

 evsel = perf_evsel__new(&attr2);
 __T("failed to create evsel2", evsel);

 perf_evlist__add(evlist, evsel);

 perf_evlist__set_leader(evlist);
 __T("failed to set leader", leader->leader == leader);
 __T("failed to set leader", evsel->leader  == leader);

 perf_evlist__set_maps(evlist, NULL, threads);

 err = perf_evlist__open(evlist);
 __T("failed to open evlist", err == 0);

 perf_evlist__for_each_evsel(evlist, evsel) {
  perf_evsel__read(evsel, 0, 0, &counts);
  __T("failed to read value for evsel", counts.val == 0);
 }

 perf_evlist__enable(evlist);

 perf_evlist__for_each_evsel(evlist, evsel) {
  perf_evsel__read(evsel, 0, 0, &counts);
  __T("failed to read value for evsel", counts.val != 0);
 }

 perf_evlist__disable(evlist);

 perf_evlist__close(evlist);
 perf_evlist__delete(evlist);

 perf_thread_map__put(threads);
 return 0;
}

static int test_mmap_thread(void)
{
 struct perf_evlist *evlist;
 struct perf_evsel *evsel;
 struct perf_mmap *map;
 struct perf_cpu_map *cpus;
 struct perf_thread_map *threads;
 struct perf_event_attr attr = {
  .type             = PERF_TYPE_TRACEPOINT,
  .sample_period    = 1,
  .wakeup_watermark = 1,
  .disabled         = 1,
 };
 char path[PATH_MAX];
 int id, err, pid, go_pipe[2];
 union perf_event *event;
 int count = 0;

 snprintf(path, PATH_MAX, "%s/kernel/debug/tracing/events/syscalls/sys_enter_prctl/id",
   sysfs__mountpoint());

 if (filename__read_int(path, &id)) {
  tests_failed++;
  fprintf(stderr, "error: failed to get tracepoint id: %s\n", path);
  return -1;
 }

 attr.config = id;

 err = pipe(go_pipe);
 __T("failed to create pipe", err == 0);

 fflush(NULL);

 pid = fork();
 if (!pid) {
  int i;
  char bf;

  read(go_pipe[0], &bf, 1);

  /* Generate 100 prctl calls. */
  for (i = 0; i < 100; i++)
   prctl(0, 0, 0, 0, 0);

  exit(0);
 }

 threads = perf_thread_map__new_dummy();
 __T("failed to create threads", threads);

 cpus = perf_cpu_map__new_any_cpu();
 __T("failed to create cpus", cpus);

 perf_thread_map__set_pid(threads, 0, pid);

 evlist = perf_evlist__new();
 __T("failed to create evlist", evlist);

 evsel = perf_evsel__new(&attr);
 __T("failed to create evsel1", evsel);
 __T("failed to set leader", evsel->leader == evsel);

 perf_evlist__add(evlist, evsel);

 perf_evlist__set_maps(evlist, cpus, threads);

 err = perf_evlist__open(evlist);
 __T("failed to open evlist", err == 0);

 err = perf_evlist__mmap(evlist, 4);
 __T("failed to mmap evlist", err == 0);

 perf_evlist__enable(evlist);

 /* kick the child and wait for it to finish */
 write(go_pipe[1], "A", 1);
 waitpid(pid, NULL, 0);

 /*
 * There's no need to call perf_evlist__disable,
 * monitored process is dead now.
 */


 perf_evlist__for_each_mmap(evlist, map, false) {
  if (perf_mmap__read_init(map) < 0)
   continue;

  while ((event = perf_mmap__read_event(map)) != NULL) {
   count++;
   perf_mmap__consume(map);
  }

  perf_mmap__read_done(map);
 }

 /* calls perf_evlist__munmap/perf_evlist__close */
 perf_evlist__delete(evlist);

 perf_thread_map__put(threads);
 perf_cpu_map__put(cpus);

 /*
 * The generated prctl calls should match the
 * number of events in the buffer.
 */

 __T("failed count", count == 100);

 return 0;
}

static int test_mmap_cpus(void)
{
 struct perf_evlist *evlist;
 struct perf_evsel *evsel;
 struct perf_mmap *map;
 struct perf_cpu_map *cpus;
 struct perf_event_attr attr = {
  .type             = PERF_TYPE_TRACEPOINT,
  .sample_period    = 1,
  .wakeup_watermark = 1,
  .disabled         = 1,
 };
 cpu_set_t saved_mask;
 char path[PATH_MAX];
 int id, err, tmp;
 struct perf_cpu cpu;
 union perf_event *event;
 int count = 0;

 snprintf(path, PATH_MAX, "%s/kernel/debug/tracing/events/syscalls/sys_enter_prctl/id",
   sysfs__mountpoint());

 if (filename__read_int(path, &id)) {
  fprintf(stderr, "error: failed to get tracepoint id: %s\n", path);
  return -1;
 }

 attr.config = id;

 cpus = perf_cpu_map__new_online_cpus();
 __T("failed to create cpus", cpus);

 evlist = perf_evlist__new();
 __T("failed to create evlist", evlist);

 evsel = perf_evsel__new(&attr);
 __T("failed to create evsel1", evsel);
 __T("failed to set leader", evsel->leader == evsel);

 perf_evlist__add(evlist, evsel);

 perf_evlist__set_maps(evlist, cpus, NULL);

 err = perf_evlist__open(evlist);
 __T("failed to open evlist", err == 0);

 err = perf_evlist__mmap(evlist, 4);
 __T("failed to mmap evlist", err == 0);

 perf_evlist__enable(evlist);

 err = sched_getaffinity(0, sizeof(saved_mask), &saved_mask);
 __T("sched_getaffinity failed", err == 0);

 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
  cpu_set_t mask;

  CPU_ZERO(&mask);
  CPU_SET(cpu.cpu, &mask);

  err = sched_setaffinity(0, sizeof(mask), &mask);
  __T("sched_setaffinity failed", err == 0);

  prctl(0, 0, 0, 0, 0);
 }

 err = sched_setaffinity(0, sizeof(saved_mask), &saved_mask);
 __T("sched_setaffinity failed", err == 0);

 perf_evlist__disable(evlist);

 perf_evlist__for_each_mmap(evlist, map, false) {
  if (perf_mmap__read_init(map) < 0)
   continue;

  while ((event = perf_mmap__read_event(map)) != NULL) {
   count++;
   perf_mmap__consume(map);
  }

  perf_mmap__read_done(map);
 }

 /* calls perf_evlist__munmap/perf_evlist__close */
 perf_evlist__delete(evlist);

 /*
 * The generated prctl events should match the
 * number of cpus or be bigger (we are system-wide).
 */

 __T("failed count", count >= perf_cpu_map__nr(cpus));

 perf_cpu_map__put(cpus);

 return 0;
}

static double display_error(long long average,
       long long high,
       long long low,
       long long expected)
{
 double error;

 error = (((double)average - expected) / expected) * 100.0;

 __T_VERBOSE(" Expected: %lld\n", expected);
 __T_VERBOSE(" High: %lld Low: %lld Average: %lld\n",
      high, low, average);

 __T_VERBOSE(" Average Error = %.2f%%\n", error);

 return error;
}

static int test_stat_multiplexing(void)
{
 struct perf_counts_values expected_counts = { .val = 0 };
 struct perf_counts_values counts[EVENT_NUM] = {{ .val = 0 },};
 struct perf_thread_map *threads;
 struct perf_evlist *evlist;
 struct perf_evsel *evsel;
 struct perf_event_attr attr = {
  .type      = PERF_TYPE_HARDWARE,
  .config      = PERF_COUNT_HW_INSTRUCTIONS,
  .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
          PERF_FORMAT_TOTAL_TIME_RUNNING,
  .disabled    = 1,
 };
 int err, i, nonzero = 0;
 unsigned long count;
 long long max = 0, min = 0, avg = 0;
 double error = 0.0;
 s8 scaled = 0;

 /* read for non-multiplexing event count */
 threads = perf_thread_map__new_dummy();
 __T("failed to create threads", threads);

 perf_thread_map__set_pid(threads, 0, 0);

 evsel = perf_evsel__new(&attr);
 __T("failed to create evsel", evsel);

 err = perf_evsel__open(evsel, NULL, threads);
 __T("failed to open evsel", err == 0);

 err = perf_evsel__enable(evsel);
 __T("failed to enable evsel", err == 0);

 /* wait loop */
 count = WAIT_COUNT;
 while (count--)
  ;

 perf_evsel__read(evsel, 0, 0, &expected_counts);
 __T("failed to read value for evsel", expected_counts.val != 0);
 __T("failed to read non-multiplexing event count",
     expected_counts.ena == expected_counts.run);

 err = perf_evsel__disable(evsel);
 __T("failed to enable evsel", err == 0);

 perf_evsel__close(evsel);
 perf_evsel__delete(evsel);

 perf_thread_map__put(threads);

 /* read for multiplexing event count */
 threads = perf_thread_map__new_dummy();
 __T("failed to create threads", threads);

 perf_thread_map__set_pid(threads, 0, 0);

 evlist = perf_evlist__new();
 __T("failed to create evlist", evlist);

 for (i = 0; i < EVENT_NUM; i++) {
  evsel = perf_evsel__new(&attr);
  __T("failed to create evsel", evsel);

  perf_evlist__add(evlist, evsel);
 }
 perf_evlist__set_maps(evlist, NULL, threads);

 err = perf_evlist__open(evlist);
 __T("failed to open evlist", err == 0);

 perf_evlist__enable(evlist);

 /* wait loop */
 count = WAIT_COUNT;
 while (count--)
  ;

 i = 0;
 perf_evlist__for_each_evsel(evlist, evsel) {
  perf_evsel__read(evsel, 0, 0, &counts[i]);
  __T("failed to read value for evsel", counts[i].val != 0);
  i++;
 }

 perf_evlist__disable(evlist);

 min = counts[0].val;
 for (i = 0; i < EVENT_NUM; i++) {
  __T_VERBOSE("Event %2d -- Raw count = %" PRIu64 ", run = %" PRIu64 ", enable = %" PRIu64 "\n",
       i, counts[i].val, counts[i].run, counts[i].ena);

  perf_counts_values__scale(&counts[i], true, &scaled);
  if (scaled == 1) {
   __T_VERBOSE("\t Scaled count = %" PRIu64 " (%.2lf%%, %" PRIu64 "/%" PRIu64 ")\n",
        counts[i].val,
        (double)counts[i].run / (double)counts[i].ena * 100.0,
        counts[i].run, counts[i].ena);
  } else if (scaled == -1) {
   __T_VERBOSE("\t Not Running\n");
  } else {
   __T_VERBOSE("\t Not Scaling\n");
  }

  if (counts[i].val > max)
   max = counts[i].val;

  if (counts[i].val < min)
   min = counts[i].val;

  avg += counts[i].val;

  if (counts[i].val != 0)
   nonzero++;
 }

 if (nonzero != 0)
  avg = avg / nonzero;
 else
  avg = 0;

 error = display_error(avg, max, min, expected_counts.val);

 __T("Error out of range!", ((error <= 1.0) && (error >= -1.0)));

 perf_evlist__close(evlist);
 perf_evlist__delete(evlist);

 perf_thread_map__put(threads);

 return 0;
}

int test_evlist(int argc, char **argv)
{
 __T_START;

 libperf_init(libperf_print);

 test_stat_cpu();
 test_stat_thread();
 test_stat_thread_enable();
 test_mmap_thread();
 test_mmap_cpus();
 test_stat_multiplexing();

 __T_END;
 return tests_failed == 0 ? 0 : -1;
}

Messung V0.5
C=97 H=93 G=94

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.