1 /*
2 * syscall2.c
3 *
4 * All-threads getuid timing test.
5 */
6
7 #include <sys/types.h>
8 #include <sys/errno.h>
9 #include <sys/mman.h>
10 #include <time.h>
11 #include <stdio.h>
12
13 #include <machine/atomic.h>
14
15 #include "blib.h"
16
17 extern int getuid_test(void);
18
19 int
main(void)20 main(void)
21 {
22 struct timespec ts, ts2;
23 int error;
24 long long count = 0;
25 long long max;
26 int j;
27 int cpuno;
28 int ncpu;
29 int *done;
30 size_t ncpu_size;
31
32 done = mmap(NULL, 4096, PROT_READ|PROT_WRITE,
33 MAP_SHARED|MAP_ANON, -1, 0);
34
35 /*
36 * How many cpu threads are there?
37 */
38 ncpu = 0;
39 ncpu_size = sizeof(ncpu);
40 if (sysctlbyname("hw.ncpu", &ncpu, &ncpu_size, NULL, 0) < 0) {
41 perror("sysctl hw.ncpu");
42 exit(1);
43 }
44 printf("timing standard getuid() syscall, %d threads\n", ncpu);
45 printf("if using powerd, run several times\n");
46 *done = 0;
47
48 /*
49 * Approximate timing run length
50 */
51 start_timing();
52 while (stop_timing(0, NULL) == 0) {
53 for (j = 0; j < 100; ++j)
54 getuid();
55 count += 100;
56 }
57 max = count;
58
59 /*
60 * Run same length on all threads.
61 */
62 for (cpuno = 0; cpuno < ncpu; ++cpuno) {
63 if (fork() == 0) {
64 /*
65 * Give scheduler time to move threads around
66 */
67 start_timing();
68 while (stop_timing(0, NULL) == 0) {
69 for (j = 0; j < 100; ++j)
70 getuid();
71 }
72
73 /*
74 * Actual timing test is here.
75 */
76 start_timing();
77 for (count = 0; count < max; count += 100) {
78 for (j = 0; j < 100; ++j)
79 getuid();
80 }
81 stop_timing(count, "getuid() sysmsg");
82
83 /*
84 * Don't unbusy the cpu until the other threads are
85 * done.
86 */
87 atomic_add_int(done, 1);
88 while (*done < ncpu) /* wait for other threads */
89 getuid();
90 exit(0);
91 }
92 }
93 while (wait3(NULL, 0, NULL) > 0 || errno == EINTR)
94 ;
95 return 0;
96 }
97