Sync usage with man page.
[netbsd-mini2440.git] / regress / sys / kern / nameibench / nameibench.c
blobcdaefd60d70566481800608fa1b7edb2f4021e84
1 /* $NetBSD$ */
3 /*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/param.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <string.h>
38 #include <time.h>
39 #include <pthread.h>
40 #include <inttypes.h>
41 #include <signal.h>
43 #define MAXFILES 4096
45 const int primes[] = {
46 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,
47 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
48 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431,
49 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,
50 499, 503, 509, 521, 523, 541,
53 char **sa;
54 int sasize;
55 int sacnt;
56 struct timespec sts;
57 struct timespec ets;
58 pthread_barrier_t barrier;
59 pthread_mutex_t lock;
60 volatile sig_atomic_t stop;
61 double nlookups;
62 double ideal;
64 static void
65 makelist(void)
67 char buf[MAXPATHLEN], *p;
68 size_t l;
69 FILE *fp;
71 fp = popen("/usr/bin/locate x", "r");
72 if (fp == NULL) {
73 perror("popen");
74 exit(EXIT_FAILURE);
77 while (fgets(buf, sizeof(buf), fp) != NULL) {
78 l = strlen(buf) + 1;
79 p = malloc(l);
80 if (p == NULL) {
81 perror("malloc");
82 exit(EXIT_FAILURE);
84 strcpy(p, buf);
85 p[l - 2] = '\0';
86 if (sacnt == sasize) {
87 sasize += 256;
88 sa = realloc(sa, sizeof(*sa) * sasize);
89 if (sa == NULL) {
90 perror("realloc");
91 exit(EXIT_FAILURE);
94 sa[sacnt++] = p;
95 if (sacnt == MAXFILES) {
96 break;
100 fclose(fp);
103 static void
104 lookups(int idx)
106 unsigned int p, c;
108 for (c = 0, p = 0; !stop; c++) {
109 p += primes[idx];
110 if (p >= sacnt) {
111 p %= sacnt;
113 (void)access(sa[p], F_OK);
117 pthread_mutex_lock(&lock);
118 nlookups += c;
119 pthread_mutex_unlock(&lock);
122 static void
123 start(void)
126 (void)pthread_barrier_wait(&barrier);
127 if (clock_gettime(CLOCK_MONOTONIC, &sts)) {
128 perror("clock_gettime");
129 exit(EXIT_FAILURE);
133 static void
134 end(void)
137 if (clock_gettime(CLOCK_MONOTONIC, &ets)) {
138 perror("clock_gettime");
139 exit(EXIT_FAILURE);
141 (void)pthread_barrier_wait(&barrier);
144 static void *
145 thread(void *cookie)
148 start();
149 lookups((int)(uintptr_t)cookie);
150 end();
152 return NULL;
155 static void
156 sigalrm(int junk)
159 stop = (sig_atomic_t)1;
162 static void
163 run(int nt)
165 pthread_t pt;
166 double c;
167 int i;
168 long us;
170 if (pthread_barrier_init(&barrier, NULL, nt + 1)) {
171 fprintf(stderr, "pthread_barrier_init\n");
172 exit(EXIT_FAILURE);
175 nlookups = 0;
176 stop = 0;
177 for (i = 0; i < nt; i++) {
178 if (pthread_create(&pt, NULL, thread, (void *)(uintptr_t)i)) {
179 fprintf(stderr, "pthread_create\n");
180 exit(EXIT_FAILURE);
183 start();
184 alarm(10);
185 end();
186 us = (long)(ets.tv_sec * (uint64_t)1000000 + ets.tv_nsec / 1000);
187 us -= (long)(sts.tv_sec * (uint64_t)1000000 + sts.tv_nsec / 1000);
188 c = nlookups * 1000000.0 / us;
189 if (ideal == 0) {
190 ideal = c;
192 printf("%d\t%d\t%.0f\t%.0f\n", sacnt, nt, c, ideal * nt);
194 if (pthread_barrier_destroy(&barrier)) {
195 fprintf(stderr, "pthread_barrier_destroy\n");
196 exit(EXIT_FAILURE);
201 main(int argc, char **argv)
203 int i, mt;
205 (void)setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
206 if (argc < 2) {
207 mt = sysconf(_SC_NPROCESSORS_ONLN);
208 } else {
209 mt = atoi(argv[1]);
210 if (mt < 1) {
211 mt = 1;
214 if (pthread_mutex_init(&lock, NULL)) {
215 fprintf(stderr, "pthread_mutex_init\n");
216 exit(EXIT_FAILURE);
218 makelist();
219 (void)signal(SIGALRM, sigalrm);
220 printf("# nname\tnthr\tpersec\tideal\n");
221 for (i = 1; i <= mt; i++) {
222 run(i);
224 exit(EXIT_SUCCESS);