1/****************************************************************************** 2 * 3 * Copyright © International Business Machines Corp., 2006, 2008 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * NAME 20 * preempt_timing.c 21 * 22 * DESCRIPTION 23 * This program indicated the preemption delays that may be encountered 24 * by realtime apps. The program runs with the scheduling policy of 25 * SCHED_FIFO at a maximum SCHED_FIFO priority. It is bound to a single 26 * processor and its address space is locked as well. It makes successive 27 * calls to the gettimeofday() function(via inlined assembly to read the 28 * TSC).The value returned between two such consecutive calls is reported 29 * as the latency. 30 * The maximum, minimum and average delays are reported for x pairs of such 31 * calls. 32 * 33 * USAGE: 34 * Use run_auto.sh script in current directory to build and run test. 35 * 36 * AUTHOR 37 * 38 * 39 * HISTORY 40 * 41 * 42 *****************************************************************************/ 43 44#include <stdio.h> 45#include <stdlib.h> 46#include <unistd.h> 47#include <sys/time.h> 48#include <sys/types.h> 49#include <sched.h> 50#include <string.h> 51#include <errno.h> 52#include <sys/mman.h> 53#include <stdint.h> 54#include <librttest.h> 55 56#include "tst_tsc.h" 57 58#define ITERATIONS 1000000ULL 59#define INTERVALS 10 60 61void usage(void) 62{ 63 rt_help(); 64 printf("preempt_timing specific options:\n"); 65} 66 67int parse_args(int c, char *v) 68{ 69 70 int handled = 1; 71 switch (c) { 72 case 'h': 73 usage(); 74 exit(0); 75 default: 76 handled = 0; 77 break; 78 } 79 return handled; 80} 81 82unsigned long long sample_list[ITERATIONS]; 83int main(int argc, char *argv[]) 84{ 85 unsigned long long i, j, delta, min, max, avg; 86 struct sched_param param; 87 cpu_set_t mask; 88 int err; 89 90#ifdef TSC_UNSUPPORTED 91 printf("Error: test cannot be executed on an arch wihout TSC.\n"); 92 return ENOTSUP; 93#endif 94 95 max = avg = 0; 96 min = -1; 97 setup(); 98 99 rt_init("h", parse_args, argc, argv); 100 101 /* switch to SCHED_FIFO 99 */ 102 param.sched_priority = sched_get_priority_max(SCHED_FIFO); 103 err = sched_setscheduler(0, SCHED_FIFO, ¶m); 104 105 /* Check that the user has the appropriate privileges */ 106 if (err) { 107 if (errno == EPERM) { 108 fprintf(stderr, 109 "This program runs with a scheduling policy of SCHED_FIFO at priority %d\n", 110 param.sched_priority); 111 fprintf(stderr, 112 "You don't have the necessary privileges to create such a real-time process.\n"); 113 } else { 114 fprintf(stderr, "Failed to set scheduler, errno %d\n", 115 errno); 116 } 117 exit(1); 118 } 119 120 /* BIND TO A SINGLE CPU */ 121 CPU_ZERO(&mask); 122 CPU_SET(0, &mask); 123 err = sched_setaffinity(0, sizeof(mask), &mask); 124 if (err < 0) { 125 printf("Can't set affinity: %d %s\n", err, strerror(err)); 126 exit(-1); 127 } 128 129 for (j = 0; j < INTERVALS; j++) { 130 /* Collect samples */ 131 for (i = 0; i < ITERATIONS; i++) 132 rdtscll(sample_list[i]); 133 134 /* Process samples */ 135 for (i = 0; i < (ITERATIONS - 1); i++) { 136 delta = sample_list[i + 1] - sample_list[i]; 137 if (delta < min) 138 min = delta; 139 if (delta > max) 140 max = delta; 141 if (delta > 100000) 142 printf("maxd(%llu:%llu): %llu %llu = %llu\n", j, 143 i, sample_list[i], sample_list[i + 1], 144 delta); 145 avg += delta; 146 } 147 usleep(100); /*let necessary things happen */ 148 } 149 avg /= (ITERATIONS * INTERVALS); 150 151 printf("%lld pairs of gettimeofday() calls completed\n", 152 ITERATIONS * INTERVALS); 153 printf("Time between calls:\n"); 154 printf("Minimum: %llu \n", min); 155 printf("Maximum: %llu \n", max); 156 printf("Average: %llu \n", avg); 157 158 return 0; 159} 160