File Index
Files and directories
Sign in
FILE

syscall.c

File preview with syntax highlighting.

linux-6.19.14/tools/perf/bench/syscall.c C
  1/*
  2 *
  3 * syscall.c
  4 *
  5 * syscall: Benchmark for system call performance
  6 */
  7#include "../perf.h"
  8#include "../util/util.h"
  9#include <subcmd/parse-options.h>
 10#include "../builtin.h"
 11#include "bench.h"
 12
 13#include <stdio.h>
 14#include <sys/time.h>
 15#include <sys/syscall.h>
 16#include <sys/types.h>
 17#include <sys/wait.h>
 18#include <unistd.h>
 19#include <stdlib.h>
 20
 21#ifndef __NR_fork
 22#define __NR_fork -1
 23#endif
 24
 25static	int loops;
 26
 27static const struct option options[] = {
 28	OPT_INTEGER('l', "loop",	&loops,		"Specify number of loops"),
 29	OPT_END()
 30};
 31
 32static const char * const bench_syscall_usage[] = {
 33	"perf bench syscall <options>",
 34	NULL
 35};
 36
 37static void test_fork(void)
 38{
 39	pid_t pid = fork();
 40
 41	if (pid < 0) {
 42		fprintf(stderr, "fork failed\n");
 43		exit(1);
 44	} else if (pid == 0) {
 45		exit(0);
 46	} else {
 47		if (waitpid(pid, NULL, 0) < 0) {
 48			fprintf(stderr, "waitpid failed\n");
 49			exit(1);
 50		}
 51	}
 52}
 53
 54static void test_execve(void)
 55{
 56	const char *pathname = "/bin/true";
 57	char *const argv[] = { (char *)pathname, NULL };
 58	pid_t pid = fork();
 59
 60	if (pid < 0) {
 61		fprintf(stderr, "fork failed\n");
 62		exit(1);
 63	} else if (pid == 0) {
 64		execve(pathname, argv, NULL);
 65		fprintf(stderr, "execve /bin/true failed\n");
 66		exit(1);
 67	} else {
 68		if (waitpid(pid, NULL, 0) < 0) {
 69			fprintf(stderr, "waitpid failed\n");
 70			exit(1);
 71		}
 72	}
 73}
 74
 75static int bench_syscall_common(int argc, const char **argv, int syscall)
 76{
 77	struct timeval start, stop, diff;
 78	unsigned long long result_usec = 0;
 79	const char *name = NULL;
 80	int i;
 81
 82	switch (syscall) {
 83	case __NR_fork:
 84	case __NR_execve:
 85		/* Limit default loop to 10000 times to save time */
 86		loops = 10000;
 87		break;
 88	default:
 89		loops = 10000000;
 90		break;
 91	}
 92
 93	/* Options -l and --loops override default above */
 94	argc = parse_options(argc, argv, options, bench_syscall_usage, 0);
 95
 96	gettimeofday(&start, NULL);
 97
 98	for (i = 0; i < loops; i++) {
 99		switch (syscall) {
100		case __NR_getppid:
101			getppid();
102			break;
103		case __NR_getpgid:
104			getpgid(0);
105			break;
106		case __NR_fork:
107			test_fork();
108			break;
109		case __NR_execve:
110			test_execve();
111		default:
112			break;
113		}
114	}
115
116	gettimeofday(&stop, NULL);
117	timersub(&stop, &start, &diff);
118
119	switch (syscall) {
120	case __NR_getppid:
121		name = "getppid()";
122		break;
123	case __NR_getpgid:
124		name = "getpgid()";
125		break;
126	case __NR_fork:
127		name = "fork()";
128		break;
129	case __NR_execve:
130		name = "execve()";
131		break;
132	default:
133		break;
134	}
135
136	switch (bench_format) {
137	case BENCH_FORMAT_DEFAULT:
138		printf("# Executed %'d %s calls\n", loops, name);
139
140		result_usec = diff.tv_sec * 1000000;
141		result_usec += diff.tv_usec;
142
143		printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
144		       (unsigned long) diff.tv_sec,
145		       (unsigned long) (diff.tv_usec/1000));
146
147		printf(" %14lf usecs/op\n",
148		       (double)result_usec / (double)loops);
149		printf(" %'14d ops/sec\n",
150		       (int)((double)loops /
151			     ((double)result_usec / (double)1000000)));
152		break;
153
154	case BENCH_FORMAT_SIMPLE:
155		printf("%lu.%03lu\n",
156		       (unsigned long) diff.tv_sec,
157		       (unsigned long) (diff.tv_usec / 1000));
158		break;
159
160	default:
161		/* reaching here is something disaster */
162		fprintf(stderr, "Unknown format:%d\n", bench_format);
163		exit(1);
164		break;
165	}
166
167	return 0;
168}
169
170int bench_syscall_basic(int argc, const char **argv)
171{
172	return bench_syscall_common(argc, argv, __NR_getppid);
173}
174
175int bench_syscall_getpgid(int argc, const char **argv)
176{
177	return bench_syscall_common(argc, argv, __NR_getpgid);
178}
179
180int bench_syscall_fork(int argc, const char **argv)
181{
182	return bench_syscall_common(argc, argv, __NR_fork);
183}
184
185int bench_syscall_execve(int argc, const char **argv)
186{
187	return bench_syscall_common(argc, argv, __NR_execve);
188}
~/ Read-only file preview.