11.3Sad/* $NetBSD: nameibench.c,v 1.3 2019/11/23 20:37:49 ad Exp $ */ 21.1Sad 31.1Sad/*- 41.1Sad * Copyright (c) 2009 The NetBSD Foundation, Inc. 51.1Sad * All rights reserved. 61.1Sad * 71.1Sad * This code is derived from software contributed to The NetBSD Foundation 81.1Sad * by Andrew Doran. 91.1Sad * 101.1Sad * Redistribution and use in source and binary forms, with or without 111.1Sad * modification, are permitted provided that the following conditions 121.1Sad * are met: 131.1Sad * 1. Redistributions of source code must retain the above copyright 141.1Sad * notice, this list of conditions and the following disclaimer. 151.1Sad * 2. Redistributions in binary form must reproduce the above copyright 161.1Sad * notice, this list of conditions and the following disclaimer in the 171.1Sad * documentation and/or other materials provided with the distribution. 181.1Sad * 191.1Sad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Sad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Sad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Sad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Sad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Sad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Sad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Sad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Sad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Sad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Sad * POSSIBILITY OF SUCH DAMAGE. 301.1Sad */ 311.1Sad 321.1Sad#include <sys/param.h> 331.1Sad 341.1Sad#include <stdio.h> 351.1Sad#include <stdlib.h> 361.1Sad#include <unistd.h> 371.1Sad#include <string.h> 381.1Sad#include <time.h> 391.1Sad#include <pthread.h> 401.1Sad#include <inttypes.h> 411.1Sad#include <signal.h> 421.1Sad 431.1Sad#define MAXFILES 4096 441.1Sad 451.1Sadconst int primes[] = { 461.1Sad 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 471.1Sad 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 481.1Sad 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 491.1Sad 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 501.1Sad 499, 503, 509, 521, 523, 541, 511.1Sad}; 521.1Sad 531.1Sadchar **sa; 541.3Sadu_int sasize; 551.3Sadu_int sacnt; 561.1Sadstruct timespec sts; 571.1Sadstruct timespec ets; 581.1Sadpthread_barrier_t barrier; 591.1Sadpthread_mutex_t lock; 601.1Sadvolatile sig_atomic_t stop; 611.1Saddouble nlookups; 621.1Saddouble ideal; 631.1Sad 641.1Sadstatic void 651.1Sadmakelist(void) 661.1Sad{ 671.1Sad char buf[MAXPATHLEN], *p; 681.1Sad size_t l; 691.1Sad FILE *fp; 701.1Sad 711.1Sad fp = popen("/usr/bin/locate x", "r"); 721.1Sad if (fp == NULL) { 731.1Sad perror("popen"); 741.1Sad exit(EXIT_FAILURE); 751.1Sad } 761.1Sad 771.1Sad while (fgets(buf, sizeof(buf), fp) != NULL) { 781.1Sad l = strlen(buf) + 1; 791.1Sad p = malloc(l); 801.1Sad if (p == NULL) { 811.1Sad perror("malloc"); 821.1Sad exit(EXIT_FAILURE); 831.1Sad } 841.1Sad strcpy(p, buf); 851.1Sad p[l - 2] = '\0'; 861.1Sad if (sacnt == sasize) { 871.1Sad sasize += 256; 881.1Sad sa = realloc(sa, sizeof(*sa) * sasize); 891.1Sad if (sa == NULL) { 901.1Sad perror("realloc"); 911.1Sad exit(EXIT_FAILURE); 921.1Sad } 931.1Sad } 941.1Sad sa[sacnt++] = p; 951.1Sad if (sacnt == MAXFILES) { 961.1Sad break; 971.1Sad } 981.1Sad } 991.1Sad 1001.1Sad fclose(fp); 1011.1Sad} 1021.1Sad 1031.1Sadstatic void 1041.1Sadlookups(int idx) 1051.1Sad{ 1061.3Sad u_int p, c; 1071.1Sad 1081.1Sad for (c = 0, p = 0; !stop; c++) { 1091.1Sad p += primes[idx]; 1101.1Sad if (p >= sacnt) { 1111.1Sad p %= sacnt; 1121.1Sad } 1131.1Sad (void)access(sa[p], F_OK); 1141.1Sad 1151.1Sad } 1161.1Sad 1171.1Sad pthread_mutex_lock(&lock); 1181.1Sad nlookups += c; 1191.1Sad pthread_mutex_unlock(&lock); 1201.1Sad} 1211.1Sad 1221.1Sadstatic void 1231.1Sadstart(void) 1241.1Sad{ 1251.1Sad 1261.1Sad (void)pthread_barrier_wait(&barrier); 1271.1Sad if (clock_gettime(CLOCK_MONOTONIC, &sts)) { 1281.1Sad perror("clock_gettime"); 1291.1Sad exit(EXIT_FAILURE); 1301.1Sad } 1311.1Sad} 1321.1Sad 1331.1Sadstatic void 1341.1Sadend(void) 1351.1Sad{ 1361.1Sad 1371.1Sad if (clock_gettime(CLOCK_MONOTONIC, &ets)) { 1381.1Sad perror("clock_gettime"); 1391.1Sad exit(EXIT_FAILURE); 1401.1Sad } 1411.1Sad (void)pthread_barrier_wait(&barrier); 1421.1Sad} 1431.1Sad 1441.1Sadstatic void * 1451.1Sadthread(void *cookie) 1461.1Sad{ 1471.1Sad 1481.1Sad start(); 1491.1Sad lookups((int)(uintptr_t)cookie); 1501.1Sad end(); 1511.1Sad 1521.1Sad return NULL; 1531.1Sad} 1541.1Sad 1551.1Sadstatic void 1561.1Sadsigalrm(int junk) 1571.1Sad{ 1581.1Sad 1591.1Sad stop = (sig_atomic_t)1; 1601.1Sad} 1611.1Sad 1621.1Sadstatic void 1631.1Sadrun(int nt) 1641.1Sad{ 1651.1Sad pthread_t pt; 1661.1Sad double c; 1671.1Sad int i; 1681.1Sad long us; 1691.1Sad 1701.1Sad if (pthread_barrier_init(&barrier, NULL, nt + 1)) { 1711.1Sad fprintf(stderr, "pthread_barrier_init\n"); 1721.1Sad exit(EXIT_FAILURE); 1731.1Sad } 1741.1Sad 1751.1Sad nlookups = 0; 1761.1Sad stop = 0; 1771.1Sad for (i = 0; i < nt; i++) { 1781.1Sad if (pthread_create(&pt, NULL, thread, (void *)(uintptr_t)i)) { 1791.1Sad fprintf(stderr, "pthread_create\n"); 1801.1Sad exit(EXIT_FAILURE); 1811.1Sad } 1821.1Sad } 1831.1Sad start(); 1841.1Sad alarm(10); 1851.1Sad end(); 1861.1Sad us = (long)(ets.tv_sec * (uint64_t)1000000 + ets.tv_nsec / 1000); 1871.1Sad us -= (long)(sts.tv_sec * (uint64_t)1000000 + sts.tv_nsec / 1000); 1881.1Sad c = nlookups * 1000000.0 / us; 1891.1Sad if (ideal == 0) { 1901.1Sad ideal = c; 1911.1Sad } 1921.1Sad printf("%d\t%d\t%.0f\t%.0f\n", sacnt, nt, c, ideal * nt); 1931.1Sad 1941.1Sad if (pthread_barrier_destroy(&barrier)) { 1951.1Sad fprintf(stderr, "pthread_barrier_destroy\n"); 1961.1Sad exit(EXIT_FAILURE); 1971.1Sad } 1981.1Sad} 1991.1Sad 2001.1Sadint 2011.1Sadmain(int argc, char **argv) 2021.1Sad{ 2031.1Sad int i, mt; 2041.1Sad 2051.1Sad (void)setvbuf(stdout, NULL, _IOLBF, BUFSIZ); 2061.1Sad if (argc < 2) { 2071.1Sad mt = sysconf(_SC_NPROCESSORS_ONLN); 2081.1Sad } else { 2091.1Sad mt = atoi(argv[1]); 2101.1Sad if (mt < 1) { 2111.1Sad mt = 1; 2121.1Sad } 2131.1Sad } 2141.1Sad if (pthread_mutex_init(&lock, NULL)) { 2151.1Sad fprintf(stderr, "pthread_mutex_init\n"); 2161.1Sad exit(EXIT_FAILURE); 2171.1Sad } 2181.1Sad makelist(); 2191.1Sad (void)signal(SIGALRM, sigalrm); 2201.1Sad printf("# nname\tnthr\tpersec\tideal\n"); 2211.1Sad for (i = 1; i <= mt; i++) { 2221.1Sad run(i); 2231.1Sad } 2241.1Sad exit(EXIT_SUCCESS); 2251.1Sad} 226