1/* $NetBSD: select.c,v 1.2 2008/03/21 16:03:33 ad Exp $ */ 2 3/*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * THIS IS NOT A GOOD TEST OF REALTIME DISPATCH LATENCY AND SHOULD NOT 31 * BE USED AS ONE. 32 * 33 * Two threads are involved in the test. Every 100ms the first thread 34 * writes a byte down a pipe. The second thread waits to read it. The 35 * time taken for the byte to move between threads is measured. With 36 * no arguments, it uses timeshared threads. When given any argument 37 * (junk will do) it uses realtime threads. Ctrl-C ends the test. 38 */ 39 40#include <sys/mman.h> 41#include <sys/resource.h> 42 43#include <pthread.h> 44#include <stdio.h> 45#include <stdlib.h> 46#include <unistd.h> 47#include <sched.h> 48#include <limits.h> 49#include <signal.h> 50#include <err.h> 51 52pthread_barrier_t barrier; 53struct timespec start; 54int fds[2]; 55int done; 56long max = 0; 57long min = LONG_MAX; 58 59static void 60sigint(int junk) 61{ 62 63 done = 1; 64} 65 66static void * 67reader(void *cookie) 68{ 69 struct timespec end; 70 char buf[1]; 71 long val; 72 73 for (;;) { 74 (void)pthread_barrier_wait(&barrier); 75 if (read(fds[0], buf, sizeof(buf)) == -1) { 76 err(1, "read"); 77 } 78 clock_gettime(CLOCK_MONOTONIC, &end); 79 timespecsub(&end, &start, &end); 80 val = (long)end.tv_sec * 1000000000 + (long)end.tv_nsec; 81 printf("%ld\n", val); 82 if (val > max) 83 max = val; 84 if (val < min) 85 min = val; 86 } 87} 88 89int 90main(int argc, char *argv[]) 91{ 92 static struct timespec delay = { 0, 100000000 }; /* 100ms */ 93 struct sched_param sp; 94 pthread_t pt; 95 char buf[1]; 96 97 if (geteuid() != 0) { 98 errx(1, "run me as root"); 99 } 100 if (pipe(fds)) { 101 err(1, "pipe"); 102 } 103 pthread_barrier_init(&barrier, NULL, 2); 104 if (pthread_create(&pt, NULL, reader, NULL)) { 105 errx(1, "pthread_create failed"); 106 } 107 if (mlockall(MCL_CURRENT | MCL_FUTURE)) { 108 err(1, "mlockall"); 109 } 110 if (signal(SIGINT, sigint)) { 111 err(1, "siginal"); 112 } 113 if (argc != 1) { 114 /* Have an argument, use realtime priorities. */ 115 sp.sched_priority = sched_get_priority_max(SCHED_FIFO) - 2; 116 if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) { 117 errx(1, "pthread_setschedparam"); 118 } 119 sp.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1; 120 if (pthread_setschedparam(pt, SCHED_FIFO, &sp)) { 121 errx(1, "pthread_setschedparam"); 122 } 123 } else { 124 /* Not realtime, set the maximum timeshared priority. */ 125 if (setpriority(PRIO_PROCESS, 0, -20)) { 126 err(1, "setpriority"); 127 } 128 } 129 130 do { 131 (void)pthread_barrier_wait(&barrier); 132 while (nanosleep(&delay, NULL) != 0) { 133 /* nothing */ 134 } 135 clock_gettime(CLOCK_MONOTONIC, &start); 136 if (write(fds[1], buf, sizeof(buf)) == -1) { 137 err(1, "write"); 138 } 139 } while (!done); 140 141 printf("\nmin %ldns, max=%ldns\n", min, max); 142 return 0; 143} 144