16acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak/****************************************************************************** 26acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 31378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * Copyright © International Business Machines Corp., 2006-2008 46acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 56acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * This program is free software; you can redistribute it and/or modify 66acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * it under the terms of the GNU General Public License as published by 76acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * the Free Software Foundation; either version 2 of the License, or 86acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * (at your option) any later version. 96acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 106acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * This program is distributed in the hope that it will be useful, 116acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * but WITHOUT ANY WARRANTY; without even the implied warranty of 126acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 136acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * the GNU General Public License for more details. 146acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 156acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * You should have received a copy of the GNU General Public License 166acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * along with this program; if not, write to the Free Software 174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 186acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 196acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * NAME 206acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * sched_jitter.c 216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * DESCRIPTION 236acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * This test measures scheduling jitter w/ realtime processes. 246acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 251378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * It spawns a realtime thread that repeatedly times how long it takes to 261378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * do a fixed amount of work. It then prints out the maximum jitter seen 271378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * (longest execution time - the shortest execution time). 281378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * It also spawns off a realtime thread of higher priority that simply 291378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * wakes up and goes back to sleep. This tries to measure how much overhead 301378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * the scheduler adds in switching quickly to another task and back. 316acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * USAGE: 336acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * Use run_auto.sh script in current directory to build and run test. 346acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 356acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * AUTHOR 361378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * John Stultz <johnstul@us.ibm.com> 376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * HISTORY 391378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * 2006-May-05: Initial version by John Stultz <johnstul@us.ibm.com> 401378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * 2007-July-18: Support to gather stats by Ankita Garg <ankita@in.ibm.com> 416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 42aacd331fd8aefb25e888c518dae9153a1ca9d43dsubrata_modak * This line has to be added to avoid a stupid CVS problem 436acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *****************************************************************************/ 446acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdio.h> 466acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <time.h> 476acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <pthread.h> 486acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <sched.h> 496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <unistd.h> 506acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <libstats.h> 516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <librttest.h> 526acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 536acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define NUMRUNS 1000 546acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define NUMLOOPS 1000000 556acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define NSEC_PER_SEC 1000000000 566acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define WORKLEN 64 576acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define ISLEEP 50000 586acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 596acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint array[WORKLEN]; 606acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovolatile int flag; /*let interrupter know we're done */ 626acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 636acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid usage(void) 646acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 657d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper rt_help(); 667d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper printf("sched_jitter specific options:\n"); 676acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 696acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint parse_args(int c, char *v) 706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 727d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper int handled = 1; 737d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper switch (c) { 74354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'h': 75354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(); 76354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(0); 77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao default: 78354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao handled = 0; 79354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 807d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper } 817d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper return handled; 826acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 836acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaounsigned long long ts_sub(struct timespec a, struct timespec b) 856acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 866acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak unsigned long long first, second; 876acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 886acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak first = (unsigned long long)a.tv_sec * NSEC_PER_SEC + a.tv_nsec; 896acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak second = (unsigned long long)b.tv_sec * NSEC_PER_SEC + b.tv_nsec; 906acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak return first - second; 916acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 926acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 936acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid print_unit(unsigned long long val) 946acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 956acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak if (val > 1000000) 96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("%f ms\n", (float)(val) / 1000000); 976acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak else if (val > 1000) 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("%f us\n", (float)(val) / 1000); 996acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak else 1006acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak printf("%f ns\n", (float)val); 1016acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1026acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 1036acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1046acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid do_work(int runs) 1056acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 1066acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak int i, j; 107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < runs; i++) { 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (j = 0; j < WORKLEN - 1; j++) 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao array[j] = array[j] + array[j + 1]; 110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (j = 0; j < WORKLEN - 1; j++) 111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao array[j] = array[j] - array[j + 1]; 1126acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak } 1136acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 1146acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid *thread_worker(void *arg) 1166acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 1176acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak struct timespec start, stop; 1186acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak int i; 1196acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak unsigned long long delta; 120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long long min = -1, max = 0; 1216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak stats_container_t dat; 1231897ec4e75abb88c0c249e759036b20a339e456csubrata_modak stats_record_t rec; 1246acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1256acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak stats_container_init(&dat, NUMRUNS); 1266acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < NUMRUNS; i++) { 1286acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do_work(1); /* warm cache */ 1306acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1316acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak /* do test */ 1326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak clock_gettime(CLOCK_MONOTONIC, &start); 1336acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak do_work(NUMLOOPS); 1346acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak clock_gettime(CLOCK_MONOTONIC, &stop); 1356acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1366acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak /* calc delta, min and max */ 1376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak delta = ts_sub(stop, start); 1386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak if (delta < min) 1396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak min = delta; 140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (delta > max) 1416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak max = delta; 1421897ec4e75abb88c0c249e759036b20a339e456csubrata_modak rec.x = i; 1431897ec4e75abb88c0c249e759036b20a339e456csubrata_modak rec.y = delta; 1441897ec4e75abb88c0c249e759036b20a339e456csubrata_modak stats_container_append(&dat, rec); 1456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1466acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak printf("delta: %llu ns\n", delta); 147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usleep(1); /* let other things happen */ 1486acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak } 1496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1506acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak printf("max jitter: "); 1516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak print_unit(max - min); 152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao stats_container_save("samples", "Scheduling Jitter Scatter Plot", 153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Iteration", "Delay (ns)", &dat, "points"); 1546acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak return NULL; 1556acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 1566acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 157354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid *thread_interrupter(void *arg) 1586acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 1596acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak while (!flag) 160354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usleep(ISLEEP); 1616acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak return NULL; 1626acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 1636acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1646acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint main(int argc, char *argv[]) 1656acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 1664ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak int worker, interrupter; 1674ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak 1686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak setup(); 1696acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rt_init("h", parse_args, argc, argv); 1716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1724ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak interrupter = create_fifo_thread(thread_interrupter, NULL, 80); 1736acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak sleep(1); 1744ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak worker = create_fifo_thread(thread_worker, NULL, 10); 1756acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1764ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak join_thread(worker); 1776acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak flag = 1; 1784ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak join_thread(interrupter); 1796acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 180ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis return 0; 181ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis} 182