static int parse_cpus_opt(const struct option *opt, const char *arg, int unset); static int parse_nodes_opt(const struct option *opt, const char *arg, int unset); struct params p0; static const struct option options[] = { OPT_INTEGER('p', "nr_proc" , &p0.nr_proc, "number of processes"), OPT_INTEGER('t', "nr_threads" , &p0.nr_threads, "number of threads per process"), OPT_STRING('G', "mb_global" , &p0.mb_global_str, "MB", "global memory (MBs)"), OPT_STRING('P', "mb_proc" , &p0.mb_proc_str, "MB", "process memory (MBs)"), OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"), OPT_STRING('T', "mb_thread" , &p0.mb_thread_str, "MB", "thread memory (MBs)"), OPT_UINTEGER('l', "nr_loops" , &p0.nr_loops, "max number of loops to run"), OPT_UINTEGER('s', "nr_secs" , &p0.nr_secs, "max number of seconds to run"), OPT_UINTEGER('u', "usleep" , &p0.sleep_usecs, "usecs to sleep per loop iteration"), OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"), OPT_BOOLEAN('W', "data_writes" , &p0.data_writes, "access the data via writes (can be mixed with -R)"), OPT_BOOLEAN('B', "data_backwards", &p0.data_backwards, "access the data backwards as well"), OPT_BOOLEAN('Z', "data_zero_memset", &p0.data_zero_memset,"access the data via glibc bzero only"), OPT_BOOLEAN('r', "data_rand_walk", &p0.data_rand_walk, "access the data with random (32bit LFSR) walk"), OPT_BOOLEAN('z', "init_zero" , &p0.init_zero, "bzero the initial allocations"), OPT_BOOLEAN('I', "init_random" , &p0.init_random, "randomize the contents of the initial allocations"), OPT_BOOLEAN('0', "init_cpu0" , &p0.init_cpu0, "do the initial allocations on CPU#0"), OPT_INTEGER('x', "perturb_secs", &p0.perturb_secs, "perturb thread 0/0 every X secs, to test convergence stability"),
static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) { int rec_argc, i = 0, j; const char **rec_argv; int ret; bool all_user = false, all_kernel = false; struct option options[] = { OPT_CALLBACK('e', "event", &mem, "event", "event selector. use 'perf mem record -e list' to list available events", parse_record_events), OPT_UINTEGER(0, "ldlat", &perf_mem_events__loads_ldlat, "mem-loads latency"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), OPT_BOOLEAN('U', "all-user", &all_user, "collect only user level data"), OPT_BOOLEAN('K', "all-kernel", &all_kernel, "collect only kernel level data"), OPT_END() }; argc = parse_options(argc, argv, options, record_mem_usage, PARSE_OPT_KEEP_UNKNOWN); rec_argc = argc + 9; /* max number of arguments */ rec_argv = calloc(rec_argc + 1, sizeof(char *)); if (!rec_argv) return -1; rec_argv[i++] = "record"; if (mem->operation & MEM_OPERATION_LOAD) perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true; if (mem->operation & MEM_OPERATION_STORE) perf_mem_events[PERF_MEM_EVENTS__STORE].record = true; if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record) rec_argv[i++] = "-W"; rec_argv[i++] = "-d"; if (mem->phys_addr) rec_argv[i++] = "--phys-data"; for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { if (!perf_mem_events[j].record) continue; if (!perf_mem_events[j].supported) { pr_err("failed: event '%s' not supported\n", perf_mem_events__name(j)); free(rec_argv); return -1; } rec_argv[i++] = "-e"; rec_argv[i++] = perf_mem_events__name(j); }; if (all_user) rec_argv[i++] = "--all-user"; if (all_kernel) rec_argv[i++] = "--all-kernel"; for (j = 0; j < argc; j++, i++) rec_argv[i] = argv[j]; if (verbose > 0) { pr_debug("calling: record "); while (rec_argv[j]) { pr_debug("%s ", rec_argv[j]); j++; } pr_debug("\n"); } ret = cmd_record(i, rec_argv); free(rec_argv); return ret; }
/* * How many tasks to requeue at a time. * Default to 1 in order to make the kernel work more. */ static unsigned int nrequeue = 1; static pthread_t *worker; static bool done = false, silent = false, fshared = false; static pthread_mutex_t thread_lock; static pthread_cond_t thread_parent, thread_worker; static struct stats requeuetime_stats, requeued_stats; static unsigned int ncpus, threads_starting, nthreads = 0; static int futex_flag = 0; static const struct option options[] = { OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), OPT_UINTEGER('q', "nrequeue", &nrequeue, "Specify amount of threads to requeue at once"), OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), OPT_END() }; static const char * const bench_futex_requeue_usage[] = { "perf bench futex requeue <options>", NULL }; static void print_summary(void) { double requeuetime_avg = avg_stats(&requeuetime_stats); double requeuetime_stddev = stddev_stats(&requeuetime_stats);
struct timeval start, end, runtime; static pthread_mutex_t thread_lock; static unsigned int threads_starting; static struct stats throughput_stats; static pthread_cond_t thread_parent, thread_worker; struct worker { int tid; u_int32_t *futex; pthread_t thread; unsigned long ops; }; static const struct option options[] = { OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), OPT_UINTEGER('r', "runtime", &nsecs, "Specify runtime (in seconds)"), OPT_UINTEGER('f', "futexes", &nfutexes, "Specify amount of futexes per threads"), OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), OPT_BOOLEAN( 'a', "attached", &attached, "Use attached futexes"), OPT_END() }; static const char * const bench_futex_hash_usage[] = { "perf bench futex hash <options>", NULL }; static void *workerfn(void *arg) {
static unsigned int nwakes = 1; /* all threads will block on the same futex -- hash bucket chaos ;) */ static u_int32_t futex = 0; static pthread_t *blocked_worker; static bool done = false, silent = false, fshared = false; static unsigned int nblocked_threads = 0, nwaking_threads = 0; static pthread_mutex_t thread_lock; static pthread_cond_t thread_parent, thread_worker; static struct stats waketime_stats, wakeup_stats; static unsigned int ncpus, threads_starting; static int futex_flag = 0; static const struct option options[] = { OPT_UINTEGER('t', "threads", &nblocked_threads, "Specify amount of threads"), OPT_UINTEGER('w', "nwakers", &nwaking_threads, "Specify amount of waking threads"), OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), OPT_END() }; static const char * const bench_futex_wake_parallel_usage[] = { "perf bench futex wake-parallel <options>", NULL }; static void *waking_workerfn(void *arg) { struct thread_data *waker = (struct thread_data *) arg; struct timeval start, end;
/* * How many wakeups to do at a time. * Default to 1 in order to make the kernel work more. */ static unsigned int nwakes = 1; pthread_t *worker; static bool done = false, silent = false, fshared = false; static pthread_mutex_t thread_lock; static pthread_cond_t thread_parent, thread_worker; static struct stats waketime_stats, wakeup_stats; static unsigned int ncpus, threads_starting, nthreads = 0; static int futex_flag = 0; static const struct option options[] = { OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), OPT_UINTEGER('w', "nwakes", &nwakes, "Specify amount of threads to wake at once"), OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), OPT_END() }; static const char * const bench_futex_wake_usage[] = { "perf bench futex wake <options>", NULL }; static void *workerfn(void *arg __maybe_unused) { pthread_mutex_lock(&thread_lock); threads_starting--;
/* Close the fds we have left */ if (!thread_mode) for (i = 0; i < num_fds; i++) close(snd_ctx->out_fds[i]); /* Return number of children to reap */ return num_fds * 2; } static const struct option options[] = { OPT_BOOLEAN('p', "pipe", &use_pipes, "Use pipe() instead of socketpair()"), OPT_BOOLEAN('t', "thread", &thread_mode, "Be multi thread instead of multi process"), OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"), OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"), OPT_END() }; static const char * const bench_sched_message_usage[] = { "perf bench sched messaging <options>", NULL }; int bench_sched_messaging(int argc, const char **argv, const char *prefix __maybe_unused) { unsigned int i, total_children; struct timeval start, stop, diff; unsigned int num_fds = 20;
for_each_bench(coll, bench) printf("%14s: %s\n", bench->name, bench->summary); printf("\n"); } static const char *bench_format_str; /* Output/formatting style, exported to benchmark modules: */ int bench_format = BENCH_FORMAT_DEFAULT; unsigned int bench_repeat = 10; /* default number of times to repeat the run */ static const struct option bench_options[] = { OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"), OPT_UINTEGER('r', "repeat", &bench_repeat, "Specify amount of times to repeat the run"), OPT_END() }; static const char * const bench_usage[] = { "perf bench [<common options>] <collection> <benchmark> [<options>]", NULL }; static void print_usage(void) { struct collection *coll; int i; printf("Usage: \n"); for (i = 0; bench_usage[i]; i++)
static u_int32_t global_futex = 0; static struct worker *worker; static unsigned int nsecs = 10; static bool silent = false, multi = false; static bool done = false, fshared = false; static unsigned int ncpus, nthreads = 0; static int futex_flag = 0; struct timeval start, end, runtime; static pthread_mutex_t thread_lock; static unsigned int threads_starting; static struct stats throughput_stats; static pthread_cond_t thread_parent, thread_worker; static const struct option options[] = { OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), OPT_UINTEGER('r', "runtime", &nsecs, "Specify runtime (in seconds)"), OPT_BOOLEAN( 'M', "multi", &multi, "Use multiple futexes"), OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), OPT_END() }; static const char * const bench_futex_lock_pi_usage[] = { "perf bench futex requeue <options>", NULL }; static void print_summary(void) { unsigned long avg = avg_stats(&throughput_stats);