latency1.c revision 1.1
11.1Sad/* $NetBSD: latency1.c,v 1.1 2008/05/23 22:22:36 ad Exp $ */ 21.1Sad 31.1Sad/*- 41.1Sad * Copyright (c) 2008 The NetBSD Foundation, Inc. 51.1Sad * All rights reserved. 61.1Sad * 71.1Sad * Redistribution and use in source and binary forms, with or without 81.1Sad * modification, are permitted provided that the following conditions 91.1Sad * are met: 101.1Sad * 1. Redistributions of source code must retain the above copyright 111.1Sad * notice, this list of conditions and the following disclaimer. 121.1Sad * 2. Redistributions in binary form must reproduce the above copyright 131.1Sad * notice, this list of conditions and the following disclaimer in the 141.1Sad * documentation and/or other materials provided with the distribution. 151.1Sad * 161.1Sad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Sad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Sad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Sad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Sad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Sad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Sad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Sad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Sad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Sad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Sad * POSSIBILITY OF SUCH DAMAGE. 271.1Sad */ 281.1Sad 291.1Sad/* 301.1Sad * THIS IS NOT A GOOD TEST OF REALTIME DISPATCH LATENCY AND SHOULD NOT 311.1Sad * BE USED AS ONE. 321.1Sad * 331.1Sad * Two threads are involved in the test. Every 100ms the first thread 341.1Sad * writes a byte down a pipe. The second thread waits to read it. The 351.1Sad * time taken for the byte to move between threads is measured. With 361.1Sad * no arguments, it uses timeshared threads. When given any argument 371.1Sad * (junk will do) it uses realtime threads. Ctrl-C ends the test. 381.1Sad */ 391.1Sad 401.1Sad#include <sys/mman.h> 411.1Sad#include <sys/resource.h> 421.1Sad 431.1Sad#include <pthread.h> 441.1Sad#include <stdio.h> 451.1Sad#include <stdlib.h> 461.1Sad#include <unistd.h> 471.1Sad#include <sched.h> 481.1Sad#include <limits.h> 491.1Sad#include <signal.h> 501.1Sad#include <err.h> 511.1Sad 521.1Sadpthread_barrier_t barrier; 531.1Sadstruct timespec start; 541.1Sadint fds[2]; 551.1Sadint done; 561.1Sadlong max = 0; 571.1Sadlong min = LONG_MAX; 581.1Sad 591.1Sadstatic void 601.1Sadsigint(int junk) 611.1Sad{ 621.1Sad 631.1Sad done = 1; 641.1Sad} 651.1Sad 661.1Sadstatic void * 671.1Sadreader(void *cookie) 681.1Sad{ 691.1Sad struct timespec end; 701.1Sad char buf[1]; 711.1Sad long val; 721.1Sad 731.1Sad for (;;) { 741.1Sad (void)pthread_barrier_wait(&barrier); 751.1Sad if (read(fds[0], buf, sizeof(buf)) == -1) { 761.1Sad err(1, "read"); 771.1Sad } 781.1Sad clock_gettime(CLOCK_MONOTONIC, &end); 791.1Sad timespecsub(&end, &start, &end); 801.1Sad val = (long)end.tv_sec * 1000000000 + (long)end.tv_nsec; 811.1Sad printf("%ld\n", val); 821.1Sad if (val > max) 831.1Sad max = val; 841.1Sad if (val < min) 851.1Sad min = val; 861.1Sad } 871.1Sad} 881.1Sad 891.1Sadint 901.1Sadmain(int argc, char *argv[]) 911.1Sad{ 921.1Sad static struct timespec delay = { 0, 100000000 }; /* 100ms */ 931.1Sad struct sched_param sp; 941.1Sad pthread_t pt; 951.1Sad char buf[1]; 961.1Sad 971.1Sad if (geteuid() != 0) { 981.1Sad errx(1, "run me as root"); 991.1Sad } 1001.1Sad if (pipe(fds)) { 1011.1Sad err(1, "pipe"); 1021.1Sad } 1031.1Sad pthread_barrier_init(&barrier, NULL, 2); 1041.1Sad if (pthread_create(&pt, NULL, reader, NULL)) { 1051.1Sad errx(1, "pthread_create failed"); 1061.1Sad } 1071.1Sad if (mlockall(MCL_CURRENT | MCL_FUTURE)) { 1081.1Sad err(1, "mlockall"); 1091.1Sad } 1101.1Sad if (signal(SIGINT, sigint)) { 1111.1Sad err(1, "siginal"); 1121.1Sad } 1131.1Sad if (argc != 1) { 1141.1Sad /* Have an argument, use realtime priorities. */ 1151.1Sad sp.sched_priority = sched_get_priority_max(SCHED_FIFO) - 2; 1161.1Sad if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) { 1171.1Sad errx(1, "pthread_setschedparam"); 1181.1Sad } 1191.1Sad sp.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1; 1201.1Sad if (pthread_setschedparam(pt, SCHED_FIFO, &sp)) { 1211.1Sad errx(1, "pthread_setschedparam"); 1221.1Sad } 1231.1Sad } else { 1241.1Sad /* Not realtime, set the maximum timeshared priority. */ 1251.1Sad if (setpriority(PRIO_PROCESS, 0, -20)) { 1261.1Sad err(1, "setpriority"); 1271.1Sad } 1281.1Sad } 1291.1Sad 1301.1Sad do { 1311.1Sad (void)pthread_barrier_wait(&barrier); 1321.1Sad while (nanosleep(&delay, NULL) != 0) { 1331.1Sad /* nothing */ 1341.1Sad } 1351.1Sad clock_gettime(CLOCK_MONOTONIC, &start); 1361.1Sad if (write(fds[1], buf, sizeof(buf)) == -1) { 1371.1Sad err(1, "write"); 1381.1Sad } 1391.1Sad } while (!done); 1401.1Sad 1411.1Sad printf("\nmin %ldns, max=%ldns\n", min, max); 1421.1Sad return 0; 1431.1Sad} 144