/*- * Copyright (c) 2003 Dag-Erling Coïdan Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id$ */ #include #include #include #include #include #include #include #include static int it; #define ITERATIONS 100000 static struct result { uint64_t noclose; uint64_t rndclose; } results[ITERATIONS]; static inline uint64_t timeval2usec(struct timeval *tv) { return ((uint64_t)tv->tv_sec * (uint64_t)1000000 + (uint64_t)tv->tv_usec); } static inline uint64_t timeval_diff(struct timeval *a, struct timeval *b) { return ((b->tv_sec - a->tv_sec) * (uint64_t)1000000 + (b->tv_usec - a->tv_usec)); } static inline uint32_t lcrng(void) { static uint32_t x = 2003; return (x = x * 69069); } static void warmup(const char *fn) { int n; if ((it = open(fn, O_RDONLY)) < 0) err(1, "%s(): %s", __func__, fn); for (n = 0; n < 1000; ++n) close(dup(it)); } static void fdbench_noclose(void) { struct timeval a, b; int n; for (n = 0; n < ITERATIONS; ++n) { gettimeofday(&a, NULL); if (dup(it) < 0) break; gettimeofday(&b, NULL); results[n].noclose = timeval_diff(&a, &b); } warn("%s(): dup(%d)", __func__, n); while (n > it) close(n--); } static void fdbench_rndclose(void) { struct timeval a, b; int n; for (n = 0; n < 10; ++n) dup(it); for (; n < ITERATIONS; ++n) { close((lcrng() % n) + it + 1); if (dup(it) < 0) break; gettimeofday(&a, NULL); if (dup(it) < 0) break; gettimeofday(&b, NULL); results[n].rndclose = timeval_diff(&a, &b); } warn("%s(): dup(%d)", __func__, n); while (n > it) close(n--); } static void summarize(void) { int n; for (n = 10; n < ITERATIONS; ++n) { if (results[n].noclose == 0 || results[n].rndclose == 0) break; printf("%8d%24ju%24ju\n", n, (uintmax_t)results[n].noclose, (uintmax_t)results[n].rndclose); } } int main(void) { warmup("/dev/null"); fdbench_noclose(); fdbench_rndclose(); summarize(); exit(0); }