~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/bench/syscall.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php