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 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