16acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak/******************************************************************************
26acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
31378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *   Copyright © International Business Machines  Corp., 2007, 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
201378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     hrtimer-prio.c
216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * DESCRIPTION
231378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     Test the latency of hrtimers under rt load.
241378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     The busy_threads should run at a priority higher than the system
251378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     softirq_hrtimer, but lower than the timer_thread.  The timer_thread
261378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     measure the time it takes to return from a nanosleep call.  If the
271378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     lower priority threads can increase the latency of the higher
281378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     priority thread, it is considered a failure.
296acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
306acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * USAGE:
311378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *     Use run_auto.sh script in current directory to build and run test.
326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
336acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * AUTHOR
346acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *      Darren Hart <dvhltc@us.ibm.com>
356acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
366acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * HISTORY
371378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *      2007-Aug-08:      Initial version by Darren Hart <dvhltc@us.ibm.com>
386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
39aacd331fd8aefb25e888c518dae9153a1ca9d43dsubrata_modak *      This line has to be added to avoid a stupid CVS problem
406acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *****************************************************************************/
416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
426acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdio.h>
436acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdlib.h>
446acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <math.h>
456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <librttest.h>
466acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <libstats.h>
476acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
482ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak#define DEF_MED_PRIO 60		// (softirqd-hrtimer,98)
496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define DEF_ITERATIONS 10000
506acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define HIST_BUCKETS 100
516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define DEF_BUSY_TIME 10	// Duration of busy work in milliseconds
526acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define DEF_SLEEP_TIME 10000	// Duration of nanosleep in nanoseconds
536acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define DEF_CRITERIA 10		// maximum timer latency in microseconds
546acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
556acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic int med_prio = DEF_MED_PRIO;
562ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modakstatic int high_prio;
576acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic int busy_time = DEF_BUSY_TIME;
586acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic int iterations = DEF_ITERATIONS;
596acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic int busy_threads;
606acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
616acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic stats_container_t dat;
621897ec4e75abb88c0c249e759036b20a339e456csubrata_modakstatic stats_record_t rec;
636acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic atomic_t busy_threads_started;
646acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic unsigned long min_delta;
656acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic unsigned long max_delta;
666acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
676acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid usage(void)
686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
692ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	rt_help();
706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("hrtimer-prio specific options:\n");
71354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf("  -t#	   #:busy work time in ms, defaults to %d ms\n",
72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       DEF_BUSY_TIME);
73354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf("  -i#	   #:number of iterations, defaults to %d\n",
74354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       DEF_ITERATIONS);
757d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper	printf("  -n#	   #:number of busy threads, defaults to NR_CPUS*2\n");
76354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf
77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    ("  -f#	   #:rt fifo priority of busy threads (1,98), defaults to %d\n",
78354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	     DEF_MED_PRIO);
79354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf
80354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    ("  -m#	   #:maximum timer latency in microseconds, defaults to %d\n",
81354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	     DEF_CRITERIA);
826acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
836acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
846acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint parse_args(int c, char *v)
856acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
866acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
872ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	int handled = 1;
882ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	switch (c) {
89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'h':
90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		usage();
91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(0);
92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 't':
93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		busy_time = atoi(v);
94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'n':
96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		busy_threads = atoi(v);
97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'f':
99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		med_prio = MIN(atoi(v), 98);
100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'i':
102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		iterations = atoi(v);
103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (iterations < 100) {
104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"Number of iterations cannot be less than 100.\n");
106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(1);
107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1082ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		break;
1092ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	default:
1102ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		handled = 0;
1112ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		break;
112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return handled;
1146acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
1156acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1166acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid *busy_thread(void *thread)
1176acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
1186acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	atomic_inc(&busy_threads_started);
1196acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	while (1) {
1206acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		busy_work_ms(busy_time);
1216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		sched_yield();
1226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
1236acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	return NULL;
1246acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
1256acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1266acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid *timer_thread(void *thread)
1276acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
1286acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	int i;
1296acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	nsec_t start, end;
1306acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	unsigned long delta_us;
131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (atomic_get(&busy_threads_started) < busy_threads) {
1326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		rt_nanosleep(10000);
1336acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
134354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf("All Busy Threads started, commencing test\n");	// FIXME: use debug infrastructure
1356acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	max_delta = 0;
136354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 0; i < iterations; i++) {
1376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		start = rt_gettime();
1386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		rt_nanosleep(DEF_SLEEP_TIME);
1396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		end = rt_gettime();
140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		delta_us =
141354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    ((unsigned long)(end - start) - DEF_SLEEP_TIME) / NS_PER_US;
1421897ec4e75abb88c0c249e759036b20a339e456csubrata_modak		rec.x = i;
1431897ec4e75abb88c0c249e759036b20a339e456csubrata_modak		rec.y = delta_us;
1441897ec4e75abb88c0c249e759036b20a339e456csubrata_modak		stats_container_append(&dat, rec);
1456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		max_delta = MAX(max_delta, delta_us);
1466acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		min_delta = (i == 0) ? delta_us : MIN(min_delta, delta_us);
1476acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
1486acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	return NULL;
1496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
1506acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint main(int argc, char *argv[])
1526acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
1536acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	int ret = 1;
1546acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	int b;
1556acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	float avg_delta;
1566acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	int t_id;
1576acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	setup();
158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	busy_threads = 2 * sysconf(_SC_NPROCESSORS_ONLN);	// default busy_threads
15922a75d509c9703264b737f561067d1d8b454d9e5subrata_modak	pass_criteria = DEF_CRITERIA;
16022a75d509c9703264b737f561067d1d8b454d9e5subrata_modak	rt_init("f:i:jhn:t:", parse_args, argc, argv);
1612ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	high_prio = med_prio + 1;
1626acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1636acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	// Set main()'s prio to one above the timer_thread so it is sure to not
1646acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	// be starved
165354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (set_priority(high_prio + 1) < 0) {
166354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		printf("Failed to set main()'s priority to %d\n",
167354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       high_prio + 1);
1686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		exit(1);
1696acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
1706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("\n-------------------------------------------\n");
1726acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("High Resolution Timer Priority (Starvation)\n");
1736acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("-------------------------------------------\n\n");
1746acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Running %d iterations\n", iterations);
1756acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Running with %d busy threads\n", busy_threads);
1766acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Busy thread work time: %d\n", busy_time);
1776acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Busy thread priority: %d\n", med_prio);
1786acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Timer thread priority: %d\n", high_prio);
1796acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1806acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	stats_container_t hist;
1816acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	stats_quantiles_t quantiles;
1822ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	if (stats_container_init(&dat, iterations)) {
1832ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		printf("Cannot init stat containers for dat\n");
1842ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		exit(1);
1852ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	}
1862ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	if (stats_container_init(&hist, HIST_BUCKETS)) {
1872ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		printf("Cannot init stat containers for hist\n");
1882ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		exit(1);
1892ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	}
1902ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	if (stats_quantiles_init(&quantiles, (int)log10(iterations))) {
1912ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		printf("Cannot init stat quantiles\n");
1922ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak		exit(1);
1932ddd7378d06c49a065ad4c8b3abec011313ca590subrata_modak	}
1946acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1956acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	t_id = create_fifo_thread(timer_thread, NULL, high_prio);
1966acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	if (t_id == -1) {
1976acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		printf("Failed to create timer thread\n");
1986acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		exit(1);
1996acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (b = 0; b < busy_threads; b++) {
2016acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		if (create_fifo_thread(busy_thread, NULL, med_prio) < 0) {
2026acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			printf("Failed to create a busy thread\n");
2036acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			exit(1);
2046acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		}
2056acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
2066acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	join_thread(t_id);
2076acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2086acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	avg_delta = stats_avg(&dat);
2096acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	stats_hist(&hist, &dat);
210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	stats_container_save("samples",
211354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			     "High Resolution Timer Latency Scatter Plot",
212354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			     "Iteration", "Latency (us)", &dat, "points");
213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	stats_container_save("hist", "High Resolution Timer Latency Histogram",
214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			     "Latency (us)", "Samples", &hist, "steps");
2156acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
21622a75d509c9703264b737f561067d1d8b454d9e5subrata_modak	if (max_delta <= pass_criteria)
2176acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		ret = 0;
2186acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2196acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Minimum: %ld us\n", min_delta);
2206acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Maximum: %ld us\n", max_delta);
2216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Average: %f us\n", avg_delta);
2226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Standard Deviation: %f\n", stats_stddev(&dat));
2236acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Quantiles:\n");
224d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	stats_quantiles_calc(&dat, &quantiles);
2256acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	stats_quantiles_print(&quantiles);
226354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf("\nCriteria: Maximum wakeup latency < %lu us\n",
227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       (unsigned long)pass_criteria);
2286acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Result: %s\n", ret ? "FAIL" : "PASS");
2296acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2306acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	return ret;
231ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
232