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
201378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *      sched_latency.c
216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * DESCRIPTION
231378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *	Measure the latency involved with periodic scheduling.
241378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *   Steps:
251378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *    - A thread is created at a priority of 89.
261378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *    -	It periodically sleeps for a specified duration(period).
271378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *    - The delay is measured as
286acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
291378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *      delay = (now - start - i*period) converted to microseconds
301378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *
311378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *	where,
321378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *	now = CLOCK_MONOTONIC gettime in ns, start = CLOCK_MONOTONIC gettime
331378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *	at the start of the test, i = iteration number, period = period chosen
346acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
356acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * USAGE:
366acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *      Use run_auto.sh script in current directory to build and run test.
376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * AUTHOR
391378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *      Darren Hart <dvhltc@us.ibm.com>
406acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * HISTORY
421378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *      2006-May-10: Initial version by Darren Hart <dvhltc@us.ibm.com>
431378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *      2007-Jul-11: Quantiles added by Josh Triplett <josh@kernel.org>
441378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *      2007-Jul-12: Latency tracing added by Josh Triplett <josh@kernel.org>
456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
46aacd331fd8aefb25e888c518dae9153a1ca9d43dsubrata_modak *      This line has to be added to avoid a stupid CVS problem
476acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *****************************************************************************/
486acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdio.h>
506acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdlib.h>
516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <math.h>
526acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <librttest.h>
536acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <libstats.h>
546acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
556acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define PRIO 89
566acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak//#define PERIOD 17*NS_PER_MS
576acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak//#define ITERATIONS 100
586acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define MIN_ITERATIONS 100
596acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define DEFAULT_ITERATIONS 10000
606acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define DEF_PERIOD 5*NS_PER_MS
616acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define DEF_LOAD_MS 1
626acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define PASS_US 100
636acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#define HIST_BUCKETS 100
64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define OVERHEAD 50000		// allow for 50 us of periodic overhead (context switch, etc.)
656acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
666acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modaknsec_t start;
676acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modaknsec_t end;
686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic int ret = 0;
696acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic int iterations = 0;
706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic unsigned long long latency_threshold = 0;
716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic nsec_t period = DEF_PERIOD;
726acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakstatic unsigned int load_ms = DEF_LOAD_MS;
736acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
74d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modakstats_container_t dat;
75d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modakstats_container_t hist;
76d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modakstats_quantiles_t quantiles;
771897ec4e75abb88c0c249e759036b20a339e456csubrata_modakstats_record_t rec;
78d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak
796acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid usage(void)
806acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
816acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	rt_help();
826acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("sched_latency specific options:\n");
837d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper	printf("  -dLOAD	periodic load in ms (default 1)\n");
846acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("  -lTHRESHOLD   trace latency, with given threshold in us\n");
856acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("  -tPERIOD      period in ms (default 5)\n");
866acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("  -iITERATIONS  number of iterations (default %d)\n",
876acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	       DEFAULT_ITERATIONS);
886acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
896acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
906acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint parse_args(int c, char *v)
916acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
926acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
937d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper	int handled = 1;
947d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper	switch (c) {
95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'h':
96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		usage();
97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(0);
98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'd':
99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		load_ms = atoi(v);
100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'i':
102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		iterations = atoi(v);
103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 'l':
105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		latency_threshold = strtoull(v, NULL, 0);
106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 't':
108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		period = strtoull(v, NULL, 0) * NS_PER_MS;
109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	default:
111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		handled = 0;
112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
1137d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper	}
1147d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper	return handled;
1156acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
1166acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1176acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid *periodic_thread(void *arg)
1186acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
1196acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	int i;
120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	nsec_t delay, avg_delay = 0, start_delay, min_delay = -1ULL, max_delay =
121354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    0;
1226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	int failures = 0;
123354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	nsec_t next = 0, now = 0, sched_delta = 0, delta = 0, prev =
124354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    0, iter_start;
1256acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* wait for the specified start time */
127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	rt_nanosleep_until(start);
128021ed2522d964a634d684d810e0eb13a4ba4bf46subrata_modak
1296acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	now = rt_gettime();
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	start_delay = (now - start) / NS_PER_US;
1314ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak	iter_start = next = now;
1326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1336acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	debug(DBG_INFO, "ITERATION DELAY(US) MAX_DELAY(US) FAILURES\n");
1346acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	debug(DBG_INFO, "--------- --------- ------------- --------\n");
1356acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1366acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	if (latency_threshold) {
1376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		latency_trace_enable();
1386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		latency_trace_start();
1396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
140d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	for (i = 0; i < iterations; i++) {
1416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		/* wait for the period to start */
1426acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		next += period;
1436acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		prev = now;
1446acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		now = rt_gettime();
1456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1466acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		if (next < now) {
1476acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			printf("\nPERIOD MISSED!\n");
148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("     scheduled delta: %8llu us\n",
149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       sched_delta / 1000);
150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("	actual delta: %8llu us\n",
151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       delta / 1000);
152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("	     latency: %8llu us\n",
153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       (delta - sched_delta) / 1000);
1546acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			printf("---------------------------------------\n");
155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("      previous start: %8llu us\n",
156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       (prev - iter_start) / 1000);
157354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("		 now: %8llu us\n",
158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       (now - iter_start) / 1000);
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("     scheduled start: %8llu us\n",
160354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       (next - iter_start) / 1000);
1616acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			printf("next scheduled start is in the past!\n");
1626acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			ret = 1;
1636acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			break;
1646acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		}
1656acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
166354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		sched_delta = next - now;	/* how long we should sleep */
1676acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		delta = 0;
1686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		do {
169d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak			nsec_t new_now;
170d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak
1716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			rt_nanosleep(next - now);
172d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak			new_now = rt_gettime();
173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			delta += new_now - now;	/* how long we did sleep */
174d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak			now = new_now;
1756acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		} while (now < next);
1766acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1776acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		/* start of period */
178354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		delay =
179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    (now - iter_start - (nsec_t) (i + 1) * period) / NS_PER_US;
1801897ec4e75abb88c0c249e759036b20a339e456csubrata_modak		rec.x = i;
1811897ec4e75abb88c0c249e759036b20a339e456csubrata_modak		rec.y = delay;
1821897ec4e75abb88c0c249e759036b20a339e456csubrata_modak		stats_container_append(&dat, rec);
1831897ec4e75abb88c0c249e759036b20a339e456csubrata_modak
1846acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		if (delay < min_delay)
1856acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			min_delay = delay;
1866acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		if (delay > max_delay)
1876acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			max_delay = delay;
1880baface00a275e26dd870b88df339a9d3fbaffbesubrata_modak		if (delay > pass_criteria) {
1896acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			failures++;
1906acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			ret = 1;
1916acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		}
1926acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		avg_delay += delay;
1936acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		if (latency_threshold && delay > latency_threshold)
1946acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			break;
1956acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1966acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		/* continuous status ticker */
197354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		debug(DBG_INFO, "%9i %9llu %13llu %8i\r", i, delay, max_delay,
198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		      failures);
1996acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		fflush(stdout);
2006acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2016acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		busy_work_ms(load_ms);
2026acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
2036acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	if (latency_threshold) {
2046acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		latency_trace_stop();
205d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak		if (i != iterations) {
206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf
207354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			    ("Latency threshold (%lluus) exceeded at iteration %d\n",
208354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			     latency_threshold, i);
2096acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak			latency_trace_print();
210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			stats_container_resize(&dat, i + 1);
2116acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		}
2126acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
2136acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
214d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	/* save samples before the quantile calculation messes things up! */
215d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	stats_hist(&hist, &dat);
216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	stats_container_save("samples",
217354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			     "Periodic Scheduling Latency Scatter Plot",
218d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak			     "Iteration", "Latency (us)", &dat, "points");
219354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	stats_container_save("hist", "Periodic Scheduling Latency Histogram",
220354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			     "Latency (us)", "Samples", &hist, "steps");
221d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak
2221378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak	avg_delay /= i;
2236acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("\n\n");
2246acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Start: %4llu us: %s\n", start_delay,
225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       start_delay < pass_criteria ? "PASS" : "FAIL");
2266acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Min:   %4llu us: %s\n", min_delay,
227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       min_delay < pass_criteria ? "PASS" : "FAIL");
2286acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Max:   %4llu us: %s\n", max_delay,
229354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       max_delay < pass_criteria ? "PASS" : "FAIL");
2306acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Avg:   %4llu us: %s\n", avg_delay,
231354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       avg_delay < pass_criteria ? "PASS" : "FAIL");
2326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("StdDev: %.4f us\n", stats_stddev(&dat));
2336acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Quantiles:\n");
234d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	stats_quantiles_calc(&dat, &quantiles);
2356acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	stats_quantiles_print(&quantiles);
2366acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Failed Iterations: %d\n", failures);
2376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	return NULL;
2396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
2406acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint main(int argc, char *argv[])
2426acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
2436acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	int per_id;
2446acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	setup();
2456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2460baface00a275e26dd870b88df339a9d3fbaffbesubrata_modak	pass_criteria = PASS_US;
2474ce8327beabab97264810705c509a50c1e6330d9subrata_modak	rt_init("d:l:ht:i:", parse_args, argc, argv);
2486acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("-------------------------------\n");
2506acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Scheduling Latency\n");
2516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("-------------------------------\n\n");
2526acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
253354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (load_ms * NS_PER_MS >= period - OVERHEAD) {
254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		printf("ERROR: load must be < period - %d us\n",
255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       OVERHEAD / NS_PER_US);
2566acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		exit(1);
2576acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
2586acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2596acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	if (iterations == 0)
2606acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		iterations = DEFAULT_ITERATIONS;
2616acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	if (iterations < MIN_ITERATIONS) {
262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		printf
263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    ("Too few iterations (%d), use min iteration instead (%d)\n",
264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     iterations, MIN_ITERATIONS);
2656acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak		iterations = MIN_ITERATIONS;
2666acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	}
2676acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Running %d iterations with a period of %llu ms\n", iterations,
269354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       period / NS_PER_MS);
2706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Periodic load duration: %d ms\n", load_ms);
2716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Expected running time: %d s\n",
272354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       (int)(iterations * ((float)period / NS_PER_SEC)));
2736acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
274d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	if (stats_container_init(&dat, iterations))
275d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak		exit(1);
276d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak
277d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	if (stats_container_init(&hist, HIST_BUCKETS)) {
278d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak		stats_container_free(&dat);
279d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak		exit(1);
280d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	}
281d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak
282d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	/* use the highest value for the quantiles */
2834ada1ca5036b7ebe90f3922696f45fbc3b362ef9subrata_modak	if (stats_quantiles_init(&quantiles, (int)log10(iterations))) {
284d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak		stats_container_free(&hist);
285d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak		stats_container_free(&dat);
286d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak		exit(1);
287d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	}
288d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak
289021ed2522d964a634d684d810e0eb13a4ba4bf46subrata_modak	/* wait one quarter second to execute */
290021ed2522d964a634d684d810e0eb13a4ba4bf46subrata_modak	start = rt_gettime() + 250 * NS_PER_MS;
2914e2bab8415bfd5ddd552220203ed22c93a4617e5Cyril Hrubis	per_id = create_fifo_thread(periodic_thread, NULL, PRIO);
2926acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2936acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	join_thread(per_id);
2946acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	join_threads();
2956acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
2960baface00a275e26dd870b88df339a9d3fbaffbesubrata_modak	printf("\nCriteria: latencies < %d us\n", (int)pass_criteria);
2976acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	printf("Result: %s\n", ret ? "FAIL" : "PASS");
2986acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
299d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	stats_container_free(&dat);
300d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	stats_container_free(&hist);
301d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak	stats_quantiles_free(&quantiles);
302d14a87443fdb285045f956dfd0f45b50e2e05955subrata_modak
3036acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak	return ret;
304ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
305