All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters
@ 2012-05-11  0:59 Frank Rowand
  2012-05-11  1:02 ` [PATCH 1/2] V2: cyclictest: report large measured clock latency Frank Rowand
  2012-05-15 22:03 ` [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters John Kacur
  0 siblings, 2 replies; 4+ messages in thread
From: Frank Rowand @ 2012-05-11  0:59 UTC (permalink / raw)
  To: linux-rt-users@vger.kernel.org, williams; +Cc: jkacur, dvhart, lclaudio


cyclictest getopt_long() parameter clean up.
Clean up before following patch which will add a new option.

  Some elements of long_options were not in alphabetical order.

  Some elements of optstring were not in alphabetical order.

  '-e', '--latency' was missing help text

  short form of --duration ('D') was missing from optstring

  Change a few instances of leading spaces to tabs.

  Add white space to long_options to improve readability.

  Some cases of the switch processing the result of
    getopt_long() were not in alphabetical order.

  Did _not_ clean up option value parsing and processing.

Signed-off-by: Frank Rowand <frank.rowand@am.sony.com>
---
 src/cyclictest/cyclictest.c |  143 	73 +	70 -	0 !
 1 file changed, 73 insertions(+), 70 deletions(-)

Index: b/src/cyclictest/cyclictest.c
===================================================================
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -923,10 +923,11 @@ static void display_help(int error)
 	       "-D       --duration=t      specify a length for the test run\n"
 	       "                           default is in seconds, but 'm', 'h', or 'd' maybe added\n"
 	       "                           to modify value to minutes, hours or days\n"
+	       "-e       --latency=PM_QOS  write PM_QOS to /dev/cpu_dma_latency\n"
 	       "-E       --event           event tracing (used with -b)\n"
 	       "-f       --ftrace          function trace (when -b is active)\n"
 	       "-h       --histogram=US    dump a latency histogram to stdout after the run\n"
-               "                           (with same priority about many threads)\n"
+	       "                           (with same priority about many threads)\n"
 	       "                           US is the max time to be be tracked in microseconds\n"
 	       "-H       --histofall=US    same as -h except with an additional summary column\n"
 	       "-i INTV  --interval=INTV   base interval of thread in us default=1000\n"
@@ -944,6 +945,8 @@ static void display_help(int error)
 	       "-Q       --priospread       spread priority levels starting at specified value\n"
 	       "-r       --relative        use relative timer instead of absolute\n"
 	       "-s       --system          use sys_nanosleep and sys_setitimer\n"
+	       "-S       --smp             Standard SMP testing: options -a -t -n and\n"
+	       "                           same priority of all threads\n"
 	       "-t       --threads         one thread per available processor\n"
 	       "-t [NUM] --threads=NUM     number of threads:\n"
 	       "                           without NUM, threads = max_cpus\n"
@@ -951,16 +954,14 @@ static void display_help(int error)
 	       "-T TRACE --tracer=TRACER   set tracing function\n"
 	       "    configured tracers: %s\n"
 	       "-u       --unbuffered      force unbuffered output for live processing\n"
+	       "-U       --numa            Standard NUMA testing (similar to SMP option)\n"
+	       "                           thread data structures allocated from local node\n"
 	       "-v       --verbose         output values on stdout for statistics\n"
 	       "                           format: n:c:v n=tasknum c=count v=value in us\n"
-               "-w       --wakeup          task wakeup tracing (used with -b)\n"
-               "-W       --wakeuprt        rt task wakeup tracing (used with -b)\n"
-               "-y POLI  --policy=POLI     policy of realtime thread, POLI may be fifo(default) or rr\n"
-               "                           format: --policy=fifo(default) or --policy=rr\n"
-	       "-S       --smp             Standard SMP testing: options -a -t -n and\n"
-               "                           same priority of all threads\n"
-	       "-U       --numa            Standard NUMA testing (similar to SMP option)\n"
-               "                           thread data structures allocated from local node\n",
+	       "-w       --wakeup          task wakeup tracing (used with -b)\n"
+	       "-W       --wakeuprt        rt task wakeup tracing (used with -b)\n"
+	       "-y POLI  --policy=POLI     policy of realtime thread, POLI may be fifo(default) or rr\n"
+	       "                           format: --policy=fifo(default) or --policy=rr\n",
 	       tracers
 		);
 	if (error)
@@ -1044,48 +1045,51 @@ static void process_options (int argc, c
 
 	for (;;) {
  		int option_index = 0;
-		/** Options for getopt */
+		/*
+		 * Options for getopt
+		 * Ordered alphabetically by single letter name
+		 */
 		static struct option long_options[] = {
-			{"affinity", optional_argument, NULL, 'a'},
-			{"breaktrace", required_argument, NULL, 'b'},
-			{"preemptirqs", no_argument, NULL, 'B'},
-			{"clock", required_argument, NULL, 'c'},
-			{"context", no_argument, NULL, 'C'},
-			{"distance", required_argument, NULL, 'd'},
-			{"event", no_argument, NULL, 'E'},
-			{"ftrace", no_argument, NULL, 'f'},
-			{"histogram", required_argument, NULL, 'h'},
-			{"histofall", required_argument, NULL, 'H'},
-			{"interval", required_argument, NULL, 'i'},
-			{"irqsoff", no_argument, NULL, 'I'},
-			{"loops", required_argument, NULL, 'l'},
-			{"mlockall", no_argument, NULL, 'm' },
-			{"refresh_on_max", no_argument, NULL, 'M' },
-			{"nanosleep", no_argument, NULL, 'n'},
-			{"nsecs", no_argument, NULL, 'N'},
-			{"oscope", required_argument, NULL, 'o'},
-			{"priority", required_argument, NULL, 'p'},
-                        {"policy", required_argument, NULL, 'y'},
-			{"preemptoff", no_argument, NULL, 'P'},
-			{"quiet", no_argument, NULL, 'q'},
-			{"relative", no_argument, NULL, 'r'},
-			{"system", no_argument, NULL, 's'},
-			{"threads", optional_argument, NULL, 't'},
-			{"unbuffered", no_argument, NULL, 'u'},
-			{"verbose", no_argument, NULL, 'v'},
-			{"duration",required_argument, NULL, 'D'},
-                        {"wakeup", no_argument, NULL, 'w'},
-                        {"wakeuprt", no_argument, NULL, 'W'},
-			{"help", no_argument, NULL, '?'},
-			{"tracer", required_argument, NULL, 'T'},
-			{"traceopt", required_argument, NULL, 'O'},
-			{"smp", no_argument, NULL, 'S'},
-			{"numa", no_argument, NULL, 'U'},
-			{"latency", required_argument, NULL, 'e'},
-			{"priospread", no_argument, NULL, 'Q'},
+			{"affinity",         optional_argument, NULL, 'a'},
+			{"breaktrace",       required_argument, NULL, 'b'},
+			{"preemptirqs",      no_argument,       NULL, 'B'},
+			{"clock",            required_argument, NULL, 'c'},
+			{"context",          no_argument,       NULL, 'C'},
+			{"distance",         required_argument, NULL, 'd'},
+			{"duration",         required_argument, NULL, 'D'},
+			{"latency",          required_argument, NULL, 'e'},
+			{"event",            no_argument,       NULL, 'E'},
+			{"ftrace",           no_argument,       NULL, 'f'},
+			{"histogram",        required_argument, NULL, 'h'},
+			{"histofall",        required_argument, NULL, 'H'},
+			{"interval",         required_argument, NULL, 'i'},
+			{"irqsoff",          no_argument,       NULL, 'I'},
+			{"loops",            required_argument, NULL, 'l'},
+			{"mlockall",         no_argument,       NULL, 'm'},
+			{"refresh_on_max",   no_argument,       NULL, 'M'},
+			{"nanosleep",        no_argument,       NULL, 'n'},
+			{"nsecs",            no_argument,       NULL, 'N'},
+			{"oscope",           required_argument, NULL, 'o'},
+			{"traceopt",         required_argument, NULL, 'O'},
+			{"priority",         required_argument, NULL, 'p'},
+			{"preemptoff",       no_argument,       NULL, 'P'},
+			{"quiet",            no_argument,       NULL, 'q'},
+			{"priospread",       no_argument,       NULL, 'Q'},
+			{"relative",         no_argument,       NULL, 'r'},
+			{"system",           no_argument,       NULL, 's'},
+			{"smp",              no_argument,       NULL, 'S'},
+			{"threads",          optional_argument, NULL, 't'},
+			{"tracer",           required_argument, NULL, 'T'},
+			{"unbuffered",       no_argument,       NULL, 'u'},
+			{"numa",             no_argument,       NULL, 'U'},
+			{"verbose",          no_argument,       NULL, 'v'},
+			{"wakeup",           no_argument,       NULL, 'w'},
+			{"wakeuprt",         no_argument,       NULL, 'W'},
+			{"policy",           required_argument, NULL, 'y'},
+			{"help",             no_argument,       NULL, '?'},
 			{NULL, 0, NULL, 0}
 		};
-		int c = getopt_long(argc, argv, "a::b:Bc:Cd:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:e:",
+		int c = getopt_long(argc, argv, "a::b:Bc:Cd:D:e:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:",
 				    long_options, &option_index);
 		if (c == -1)
 			break;
@@ -1109,6 +1113,13 @@ static void process_options (int argc, c
 		case 'c': clocksel = atoi(optarg); break;
 		case 'C': tracetype = CTXTSWITCH; break;
 		case 'd': distance = atoi(optarg); break;
+		case 'D': duration = parse_time_string(optarg); break;
+		case 'e': /* power management latency target value */
+			  /* note: default is 0 (zero) */
+			latency_target_value = atoi(optarg);
+			if (latency_target_value < 0)
+				latency_target_value = 0;
+			break;
 		case 'E': enable_events = 1; break;
 		case 'f': tracetype = FUNCTION; ftrace = 1; break;
 		case 'H': histofall = 1; /* fall through */
@@ -1124,6 +1135,8 @@ static void process_options (int argc, c
 			}
 			break;
 		case 'l': max_cycles = atoi(optarg); break;
+		case 'm': lockall = 1; break;
+		case 'M': refresh_on_max = 1; break;
 		case 'n': use_nanosleep = MODE_CLOCK_NANOSLEEP; break;
 		case 'N': use_nsecs = 1; break;
 		case 'o': oscope_reduction = atoi(optarg); break;
@@ -1146,6 +1159,14 @@ static void process_options (int argc, c
 		case 'Q': priospread = 1; break;
 		case 'r': timermode = TIMER_RELTIME; break;
 		case 's': use_system = MODE_SYS_OFFSET; break;
+		case 'S':  /* SMP testing */
+			if (numa)
+				fatal("numa and smp options are mutually exclusive\n");
+			smp = 1;
+			num_threads = max_cpus;
+			setaffinity = AFFINITY_USEALL;
+			use_nanosleep = MODE_CLOCK_NANOSLEEP;
+			break;
 		case 't':
 			if (smp) {
 				warn("-t ignored due to --smp\n");
@@ -1163,22 +1184,6 @@ static void process_options (int argc, c
 			strncpy(tracer, optarg, sizeof(tracer)); 
 			break;
 		case 'u': setvbuf(stdout, NULL, _IONBF, 0); break;
-		case 'v': verbose = 1; break;
-		case 'm': lockall = 1; break;
-		case 'M': refresh_on_max = 1; break;
-		case 'D': duration = parse_time_string(optarg);
-			break;
-                case 'w': tracetype = WAKEUP; break;
-                case 'W': tracetype = WAKEUPRT; break;
-                case 'y': handlepolicy(optarg); break;
-		case 'S':  /* SMP testing */
-			if (numa)
-				fatal("numa and smp options are mutually exclusive\n");
-			smp = 1;
-			num_threads = max_cpus;
-			setaffinity = AFFINITY_USEALL;
-			use_nanosleep = MODE_CLOCK_NANOSLEEP;
-			break;
 		case 'U':  /* NUMA testing */
 			if (smp)
 				fatal("numa and smp options are mutually exclusive\n");
@@ -1194,12 +1199,10 @@ static void process_options (int argc, c
 			warn("ignoring --numa or -U\n");
 #endif
 			break;
-		case 'e': /* power management latency target value */
-			  /* note: default is 0 (zero) */
-			latency_target_value = atoi(optarg);
-			if (latency_target_value < 0)
-				latency_target_value = 0;
-			break;
+		case 'v': verbose = 1; break;
+		case 'w': tracetype = WAKEUP; break;
+		case 'W': tracetype = WAKEUPRT; break;
+		case 'y': handlepolicy(optarg); break;
 
 		case '?': display_help(0); break;
 		}


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] V2: cyclictest: report large measured clock latency
  2012-05-11  0:59 [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters Frank Rowand
@ 2012-05-11  1:02 ` Frank Rowand
  2012-05-15 22:08   ` John Kacur
  2012-05-15 22:03 ` [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters John Kacur
  1 sibling, 1 reply; 4+ messages in thread
From: Frank Rowand @ 2012-05-11  1:02 UTC (permalink / raw)
  To: linux-rt-users@vger.kernel.org, williams@redhat.com
  Cc: jkacur@redhat.com, dvhart@linux.intel.com, lclaudio@uudg.org


V2: suggested by "Luis Claudio R. Goncalves" <lclaudio@uudg.org>
    Change iterations over calling clock_gettime() from a loop count
    to a time duration.


cyclictest: ARM panda clock resolution will be ~30 usec unless
CONFIG_OMAP_32K_TIMER=n, resulting in a poor latency report.

This patch does _not_ fix the problem, it merely provides the
instrumentation to make it visible.  The value of measured
resolution is useful information for any system.

Signed-off-by: Frank Rowand <frank.rowand@am.sony.com>
---
 src/cyclictest/cyclictest.c |  110 	109 +	1 -	0 !
 1 file changed, 109 insertions(+), 1 deletion(-)

Index: b/src/cyclictest/cyclictest.c
===================================================================
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -174,6 +174,8 @@ static int use_nsecs = 0;
 static int refresh_on_max;
 static int force_sched_other;
 static int priospread = 0;
+static int check_clock_resolution;
+static int ct_debug;
 
 static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER;
 static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -944,6 +946,9 @@ static void display_help(int error)
 	       "-q       --quiet           print only a summary on exit\n"
 	       "-Q       --priospread       spread priority levels starting at specified value\n"
 	       "-r       --relative        use relative timer instead of absolute\n"
+	       "-R       --resolution      check clock resolution, calling clock_gettime() many\n"
+	       "                           times.  list of clock_gettime() values will be\n"
+	       "                           reported with -X\n"
 	       "-s       --system          use sys_nanosleep and sys_setitimer\n"
 	       "-S       --smp             Standard SMP testing: options -a -t -n and\n"
 	       "                           same priority of all threads\n"
@@ -960,6 +965,7 @@ static void display_help(int error)
 	       "                           format: n:c:v n=tasknum c=count v=value in us\n"
 	       "-w       --wakeup          task wakeup tracing (used with -b)\n"
 	       "-W       --wakeuprt        rt task wakeup tracing (used with -b)\n"
+	       "-X       --dbg_cyclictest  print info useful for debugging cyclictest\n"
 	       "-y POLI  --policy=POLI     policy of realtime thread, POLI may be fifo(default) or rr\n"
 	       "                           format: --policy=fifo(default) or --policy=rr\n",
 	       tracers
@@ -1076,6 +1082,7 @@ static void process_options (int argc, c
 			{"quiet",            no_argument,       NULL, 'q'},
 			{"priospread",       no_argument,       NULL, 'Q'},
 			{"relative",         no_argument,       NULL, 'r'},
+			{"resolution",       no_argument,       NULL, 'R'},
 			{"system",           no_argument,       NULL, 's'},
 			{"smp",              no_argument,       NULL, 'S'},
 			{"threads",          optional_argument, NULL, 't'},
@@ -1085,11 +1092,12 @@ static void process_options (int argc, c
 			{"verbose",          no_argument,       NULL, 'v'},
 			{"wakeup",           no_argument,       NULL, 'w'},
 			{"wakeuprt",         no_argument,       NULL, 'W'},
+			{"dbg_cyclictest",   no_argument,       NULL, 'X'},
 			{"policy",           required_argument, NULL, 'y'},
 			{"help",             no_argument,       NULL, '?'},
 			{NULL, 0, NULL, 0}
 		};
-		int c = getopt_long(argc, argv, "a::b:Bc:Cd:D:e:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:",
+		int c = getopt_long(argc, argv, "a::b:Bc:Cd:D:e:Efh:H:i:Il:MnNo:O:p:PmqQrRsSt::uUvD:wWXT:y:",
 				    long_options, &option_index);
 		if (c == -1)
 			break;
@@ -1158,6 +1166,7 @@ static void process_options (int argc, c
 		case 'q': quiet = 1; break;
 		case 'Q': priospread = 1; break;
 		case 'r': timermode = TIMER_RELTIME; break;
+		case 'R': check_clock_resolution = 1; break;
 		case 's': use_system = MODE_SYS_OFFSET; break;
 		case 'S':  /* SMP testing */
 			if (numa)
@@ -1202,6 +1211,7 @@ static void process_options (int argc, c
 		case 'v': verbose = 1; break;
 		case 'w': tracetype = WAKEUP; break;
 		case 'W': tracetype = WAKEUPRT; break;
+		case 'X': ct_debug = 1; break;
 		case 'y': handlepolicy(optarg); break;
 
 		case '?': display_help(0); break;
@@ -1483,6 +1493,104 @@ int main(int argc, char **argv)
 	if (check_timer())
 		warn("High resolution timers not available\n");
 
+	if (check_clock_resolution) {
+		int clock;
+		uint64_t diff;
+		int k;
+		uint64_t min_non_zero_diff = UINT64_MAX;
+		struct timespec now;
+		struct timespec prev;
+		uint64_t reported_resolution = UINT64_MAX;
+		struct timespec res;
+		struct timespec *time;
+		int times;
+		int zero_diff = 0;
+
+		clock = clocksources[clocksel];
+
+		if (clock_getres(clock, &res)) {
+			warn("clock_getres failed");
+		} else {
+			reported_resolution = (NSEC_PER_SEC * res.tv_sec) + res.tv_nsec;
+		}
+
+
+		/*
+		 * Calculate how many calls to clock_gettime are needed.
+		 * Then call it that many times.
+		 * Goal is to collect timestamps for ~ 0.001 sec.
+		 * This will reliably capture resolution <= 500 usec.
+		 */
+		times = 1000;
+		clock_gettime(clock, &prev);
+		for (k=0; k < times; k++) {
+			clock_gettime(clock, &now);
+		}
+
+		diff = calcdiff_ns(now, prev);
+		if (diff == 0) {
+			/*
+			 * No clock rollover occurred.
+			 * Use the default value for times.
+			 */
+			times = -1;
+		} else {
+			int call_time;
+			call_time = diff / times;         /* duration 1 call */
+			times = NSEC_PER_SEC / call_time; /* calls per second */
+			times /= 1000;                    /* calls per msec */
+			if (times < 1000)
+				times = 1000;
+		}
+		/* sanity check */
+		if ((times <= 0) || (times > 100000))
+			times = 100000;
+
+		time = calloc(times, sizeof(*time));
+
+		for (k=0; k < times; k++) {
+			clock_gettime(clock, &time[k]);
+		}
+
+		if (ct_debug) {
+			fprintf(stderr, "\n\nFor %d consecutive calls to clock_gettime():\n\n", times);
+			fprintf(stderr, "time, delta time (nsec)\n\n");
+		}
+
+		prev = time[0];
+		for (k=1; k < times; k++) {
+
+			diff = calcdiff_ns(time[k], prev);
+			prev = time[k];
+
+			if (diff == 0) {
+				zero_diff = 1;
+			} else if (diff < min_non_zero_diff) {
+				min_non_zero_diff = diff;
+			}
+
+			if (ct_debug)
+				fprintf(stderr, "%ld.%06ld  %5llu\n", time[k].tv_sec, time[k].tv_nsec, diff);
+		}
+
+		free(time);
+
+
+		if (verbose ||
+		    (min_non_zero_diff && (min_non_zero_diff > reported_resolution))) {
+		    	/*
+			 * Measured clock resolution includes the time to call
+			 * clock_gettime(), so it will be slightly larger than
+			 * actual resolution.
+			 */
+			fprintf(stderr, "reported clock resolution: %lld nsec\n",
+				reported_resolution);
+			fprintf(stderr, "measured clock resolution approximately: %llu nsec\n",
+				min_non_zero_diff);
+		}
+
+	}
+
 	mode = use_nanosleep + use_system;
 
 	sigemptyset(&sigset);


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters
  2012-05-11  0:59 [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters Frank Rowand
  2012-05-11  1:02 ` [PATCH 1/2] V2: cyclictest: report large measured clock latency Frank Rowand
@ 2012-05-15 22:03 ` John Kacur
  1 sibling, 0 replies; 4+ messages in thread
From: John Kacur @ 2012-05-15 22:03 UTC (permalink / raw)
  To: Frank Rowand
  Cc: linux-rt-users@vger.kernel.org, williams, jkacur, dvhart,
	lclaudio



On Thu, 10 May 2012, Frank Rowand wrote:

> 
> cyclictest getopt_long() parameter clean up.
> Clean up before following patch which will add a new option.
> 
>   Some elements of long_options were not in alphabetical order.
> 
>   Some elements of optstring were not in alphabetical order.
> 
>   '-e', '--latency' was missing help text
> 
>   short form of --duration ('D') was missing from optstring
> 
>   Change a few instances of leading spaces to tabs.
> 
>   Add white space to long_options to improve readability.
> 
>   Some cases of the switch processing the result of
>     getopt_long() were not in alphabetical order.
> 
>   Did _not_ clean up option value parsing and processing.
> 
> Signed-off-by: Frank Rowand <frank.rowand@am.sony.com>
> ---
>  src/cyclictest/cyclictest.c |  143 	73 +	70 -	0 !
>  1 file changed, 73 insertions(+), 70 deletions(-)
> 
> Index: b/src/cyclictest/cyclictest.c
> ===================================================================
> --- a/src/cyclictest/cyclictest.c
> +++ b/src/cyclictest/cyclictest.c
> @@ -923,10 +923,11 @@ static void display_help(int error)
>  	       "-D       --duration=t      specify a length for the test run\n"
>  	       "                           default is in seconds, but 'm', 'h', or 'd' maybe added\n"
>  	       "                           to modify value to minutes, hours or days\n"
> +	       "-e       --latency=PM_QOS  write PM_QOS to /dev/cpu_dma_latency\n"
>  	       "-E       --event           event tracing (used with -b)\n"
>  	       "-f       --ftrace          function trace (when -b is active)\n"
>  	       "-h       --histogram=US    dump a latency histogram to stdout after the run\n"
> -               "                           (with same priority about many threads)\n"
> +	       "                           (with same priority about many threads)\n"
>  	       "                           US is the max time to be be tracked in microseconds\n"
>  	       "-H       --histofall=US    same as -h except with an additional summary column\n"
>  	       "-i INTV  --interval=INTV   base interval of thread in us default=1000\n"
> @@ -944,6 +945,8 @@ static void display_help(int error)
>  	       "-Q       --priospread       spread priority levels starting at specified value\n"
>  	       "-r       --relative        use relative timer instead of absolute\n"
>  	       "-s       --system          use sys_nanosleep and sys_setitimer\n"
> +	       "-S       --smp             Standard SMP testing: options -a -t -n and\n"
> +	       "                           same priority of all threads\n"
>  	       "-t       --threads         one thread per available processor\n"
>  	       "-t [NUM] --threads=NUM     number of threads:\n"
>  	       "                           without NUM, threads = max_cpus\n"
> @@ -951,16 +954,14 @@ static void display_help(int error)
>  	       "-T TRACE --tracer=TRACER   set tracing function\n"
>  	       "    configured tracers: %s\n"
>  	       "-u       --unbuffered      force unbuffered output for live processing\n"
> +	       "-U       --numa            Standard NUMA testing (similar to SMP option)\n"
> +	       "                           thread data structures allocated from local node\n"
>  	       "-v       --verbose         output values on stdout for statistics\n"
>  	       "                           format: n:c:v n=tasknum c=count v=value in us\n"
> -               "-w       --wakeup          task wakeup tracing (used with -b)\n"
> -               "-W       --wakeuprt        rt task wakeup tracing (used with -b)\n"
> -               "-y POLI  --policy=POLI     policy of realtime thread, POLI may be fifo(default) or rr\n"
> -               "                           format: --policy=fifo(default) or --policy=rr\n"
> -	       "-S       --smp             Standard SMP testing: options -a -t -n and\n"
> -               "                           same priority of all threads\n"
> -	       "-U       --numa            Standard NUMA testing (similar to SMP option)\n"
> -               "                           thread data structures allocated from local node\n",
> +	       "-w       --wakeup          task wakeup tracing (used with -b)\n"
> +	       "-W       --wakeuprt        rt task wakeup tracing (used with -b)\n"
> +	       "-y POLI  --policy=POLI     policy of realtime thread, POLI may be fifo(default) or rr\n"
> +	       "                           format: --policy=fifo(default) or --policy=rr\n",
>  	       tracers
>  		);
>  	if (error)
> @@ -1044,48 +1045,51 @@ static void process_options (int argc, c
>  
>  	for (;;) {
>   		int option_index = 0;
> -		/** Options for getopt */
> +		/*
> +		 * Options for getopt
> +		 * Ordered alphabetically by single letter name
> +		 */
>  		static struct option long_options[] = {
> -			{"affinity", optional_argument, NULL, 'a'},
> -			{"breaktrace", required_argument, NULL, 'b'},
> -			{"preemptirqs", no_argument, NULL, 'B'},
> -			{"clock", required_argument, NULL, 'c'},
> -			{"context", no_argument, NULL, 'C'},
> -			{"distance", required_argument, NULL, 'd'},
> -			{"event", no_argument, NULL, 'E'},
> -			{"ftrace", no_argument, NULL, 'f'},
> -			{"histogram", required_argument, NULL, 'h'},
> -			{"histofall", required_argument, NULL, 'H'},
> -			{"interval", required_argument, NULL, 'i'},
> -			{"irqsoff", no_argument, NULL, 'I'},
> -			{"loops", required_argument, NULL, 'l'},
> -			{"mlockall", no_argument, NULL, 'm' },
> -			{"refresh_on_max", no_argument, NULL, 'M' },
> -			{"nanosleep", no_argument, NULL, 'n'},
> -			{"nsecs", no_argument, NULL, 'N'},
> -			{"oscope", required_argument, NULL, 'o'},
> -			{"priority", required_argument, NULL, 'p'},
> -                        {"policy", required_argument, NULL, 'y'},
> -			{"preemptoff", no_argument, NULL, 'P'},
> -			{"quiet", no_argument, NULL, 'q'},
> -			{"relative", no_argument, NULL, 'r'},
> -			{"system", no_argument, NULL, 's'},
> -			{"threads", optional_argument, NULL, 't'},
> -			{"unbuffered", no_argument, NULL, 'u'},
> -			{"verbose", no_argument, NULL, 'v'},
> -			{"duration",required_argument, NULL, 'D'},
> -                        {"wakeup", no_argument, NULL, 'w'},
> -                        {"wakeuprt", no_argument, NULL, 'W'},
> -			{"help", no_argument, NULL, '?'},
> -			{"tracer", required_argument, NULL, 'T'},
> -			{"traceopt", required_argument, NULL, 'O'},
> -			{"smp", no_argument, NULL, 'S'},
> -			{"numa", no_argument, NULL, 'U'},
> -			{"latency", required_argument, NULL, 'e'},
> -			{"priospread", no_argument, NULL, 'Q'},
> +			{"affinity",         optional_argument, NULL, 'a'},
> +			{"breaktrace",       required_argument, NULL, 'b'},
> +			{"preemptirqs",      no_argument,       NULL, 'B'},
> +			{"clock",            required_argument, NULL, 'c'},
> +			{"context",          no_argument,       NULL, 'C'},
> +			{"distance",         required_argument, NULL, 'd'},
> +			{"duration",         required_argument, NULL, 'D'},
> +			{"latency",          required_argument, NULL, 'e'},
> +			{"event",            no_argument,       NULL, 'E'},
> +			{"ftrace",           no_argument,       NULL, 'f'},
> +			{"histogram",        required_argument, NULL, 'h'},
> +			{"histofall",        required_argument, NULL, 'H'},
> +			{"interval",         required_argument, NULL, 'i'},
> +			{"irqsoff",          no_argument,       NULL, 'I'},
> +			{"loops",            required_argument, NULL, 'l'},
> +			{"mlockall",         no_argument,       NULL, 'm'},
> +			{"refresh_on_max",   no_argument,       NULL, 'M'},
> +			{"nanosleep",        no_argument,       NULL, 'n'},
> +			{"nsecs",            no_argument,       NULL, 'N'},
> +			{"oscope",           required_argument, NULL, 'o'},
> +			{"traceopt",         required_argument, NULL, 'O'},
> +			{"priority",         required_argument, NULL, 'p'},
> +			{"preemptoff",       no_argument,       NULL, 'P'},
> +			{"quiet",            no_argument,       NULL, 'q'},
> +			{"priospread",       no_argument,       NULL, 'Q'},
> +			{"relative",         no_argument,       NULL, 'r'},
> +			{"system",           no_argument,       NULL, 's'},
> +			{"smp",              no_argument,       NULL, 'S'},
> +			{"threads",          optional_argument, NULL, 't'},
> +			{"tracer",           required_argument, NULL, 'T'},
> +			{"unbuffered",       no_argument,       NULL, 'u'},
> +			{"numa",             no_argument,       NULL, 'U'},
> +			{"verbose",          no_argument,       NULL, 'v'},
> +			{"wakeup",           no_argument,       NULL, 'w'},
> +			{"wakeuprt",         no_argument,       NULL, 'W'},
> +			{"policy",           required_argument, NULL, 'y'},
> +			{"help",             no_argument,       NULL, '?'},
>  			{NULL, 0, NULL, 0}
>  		};
> -		int c = getopt_long(argc, argv, "a::b:Bc:Cd:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:e:",
> +		int c = getopt_long(argc, argv, "a::b:Bc:Cd:D:e:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:",
>  				    long_options, &option_index);
>  		if (c == -1)
>  			break;
> @@ -1109,6 +1113,13 @@ static void process_options (int argc, c
>  		case 'c': clocksel = atoi(optarg); break;
>  		case 'C': tracetype = CTXTSWITCH; break;
>  		case 'd': distance = atoi(optarg); break;
> +		case 'D': duration = parse_time_string(optarg); break;
> +		case 'e': /* power management latency target value */
> +			  /* note: default is 0 (zero) */
> +			latency_target_value = atoi(optarg);
> +			if (latency_target_value < 0)
> +				latency_target_value = 0;
> +			break;
>  		case 'E': enable_events = 1; break;
>  		case 'f': tracetype = FUNCTION; ftrace = 1; break;
>  		case 'H': histofall = 1; /* fall through */
> @@ -1124,6 +1135,8 @@ static void process_options (int argc, c
>  			}
>  			break;
>  		case 'l': max_cycles = atoi(optarg); break;
> +		case 'm': lockall = 1; break;
> +		case 'M': refresh_on_max = 1; break;
>  		case 'n': use_nanosleep = MODE_CLOCK_NANOSLEEP; break;
>  		case 'N': use_nsecs = 1; break;
>  		case 'o': oscope_reduction = atoi(optarg); break;
> @@ -1146,6 +1159,14 @@ static void process_options (int argc, c
>  		case 'Q': priospread = 1; break;
>  		case 'r': timermode = TIMER_RELTIME; break;
>  		case 's': use_system = MODE_SYS_OFFSET; break;
> +		case 'S':  /* SMP testing */
> +			if (numa)
> +				fatal("numa and smp options are mutually exclusive\n");
> +			smp = 1;
> +			num_threads = max_cpus;
> +			setaffinity = AFFINITY_USEALL;
> +			use_nanosleep = MODE_CLOCK_NANOSLEEP;
> +			break;
>  		case 't':
>  			if (smp) {
>  				warn("-t ignored due to --smp\n");
> @@ -1163,22 +1184,6 @@ static void process_options (int argc, c
>  			strncpy(tracer, optarg, sizeof(tracer)); 
>  			break;
>  		case 'u': setvbuf(stdout, NULL, _IONBF, 0); break;
> -		case 'v': verbose = 1; break;
> -		case 'm': lockall = 1; break;
> -		case 'M': refresh_on_max = 1; break;
> -		case 'D': duration = parse_time_string(optarg);
> -			break;
> -                case 'w': tracetype = WAKEUP; break;
> -                case 'W': tracetype = WAKEUPRT; break;
> -                case 'y': handlepolicy(optarg); break;
> -		case 'S':  /* SMP testing */
> -			if (numa)
> -				fatal("numa and smp options are mutually exclusive\n");
> -			smp = 1;
> -			num_threads = max_cpus;
> -			setaffinity = AFFINITY_USEALL;
> -			use_nanosleep = MODE_CLOCK_NANOSLEEP;
> -			break;
>  		case 'U':  /* NUMA testing */
>  			if (smp)
>  				fatal("numa and smp options are mutually exclusive\n");
> @@ -1194,12 +1199,10 @@ static void process_options (int argc, c
>  			warn("ignoring --numa or -U\n");
>  #endif
>  			break;
> -		case 'e': /* power management latency target value */
> -			  /* note: default is 0 (zero) */
> -			latency_target_value = atoi(optarg);
> -			if (latency_target_value < 0)
> -				latency_target_value = 0;
> -			break;
> +		case 'v': verbose = 1; break;
> +		case 'w': tracetype = WAKEUP; break;
> +		case 'W': tracetype = WAKEUPRT; break;
> +		case 'y': handlepolicy(optarg); break;
>  
>  		case '?': display_help(0); break;
>  		}
> 

This looks fine to me.
I've reviewed and tested it, and will add it to my own repo.

Thanks!

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] V2: cyclictest: report large measured clock latency
  2012-05-11  1:02 ` [PATCH 1/2] V2: cyclictest: report large measured clock latency Frank Rowand
@ 2012-05-15 22:08   ` John Kacur
  0 siblings, 0 replies; 4+ messages in thread
From: John Kacur @ 2012-05-15 22:08 UTC (permalink / raw)
  To: Frank Rowand
  Cc: linux-rt-users@vger.kernel.org, williams@redhat.com,
	jkacur@redhat.com, dvhart@linux.intel.com, lclaudio@uudg.org

[-- Attachment #1: Type: TEXT/PLAIN, Size: 8050 bytes --]



On Thu, 10 May 2012, Frank Rowand wrote:

> 
> V2: suggested by "Luis Claudio R. Goncalves" <lclaudio@uudg.org>
>     Change iterations over calling clock_gettime() from a loop count
>     to a time duration.
> 
> 
> cyclictest: ARM panda clock resolution will be ~30 usec unless
> CONFIG_OMAP_32K_TIMER=n, resulting in a poor latency report.
> 
> This patch does _not_ fix the problem, it merely provides the
> instrumentation to make it visible.  The value of measured
> resolution is useful information for any system.
> 
> Signed-off-by: Frank Rowand <frank.rowand@am.sony.com>
> ---
>  src/cyclictest/cyclictest.c |  110 	109 +	1 -	0 !
>  1 file changed, 109 insertions(+), 1 deletion(-)
> 
> Index: b/src/cyclictest/cyclictest.c
> ===================================================================
> --- a/src/cyclictest/cyclictest.c
> +++ b/src/cyclictest/cyclictest.c
> @@ -174,6 +174,8 @@ static int use_nsecs = 0;
>  static int refresh_on_max;
>  static int force_sched_other;
>  static int priospread = 0;
> +static int check_clock_resolution;
> +static int ct_debug;
>  
>  static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER;
>  static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;
> @@ -944,6 +946,9 @@ static void display_help(int error)
>  	       "-q       --quiet           print only a summary on exit\n"
>  	       "-Q       --priospread       spread priority levels starting at specified value\n"
>  	       "-r       --relative        use relative timer instead of absolute\n"
> +	       "-R       --resolution      check clock resolution, calling clock_gettime() many\n"
> +	       "                           times.  list of clock_gettime() values will be\n"
> +	       "                           reported with -X\n"
>  	       "-s       --system          use sys_nanosleep and sys_setitimer\n"
>  	       "-S       --smp             Standard SMP testing: options -a -t -n and\n"
>  	       "                           same priority of all threads\n"
> @@ -960,6 +965,7 @@ static void display_help(int error)
>  	       "                           format: n:c:v n=tasknum c=count v=value in us\n"
>  	       "-w       --wakeup          task wakeup tracing (used with -b)\n"
>  	       "-W       --wakeuprt        rt task wakeup tracing (used with -b)\n"
> +	       "-X       --dbg_cyclictest  print info useful for debugging cyclictest\n"
>  	       "-y POLI  --policy=POLI     policy of realtime thread, POLI may be fifo(default) or rr\n"
>  	       "                           format: --policy=fifo(default) or --policy=rr\n",
>  	       tracers
> @@ -1076,6 +1082,7 @@ static void process_options (int argc, c
>  			{"quiet",            no_argument,       NULL, 'q'},
>  			{"priospread",       no_argument,       NULL, 'Q'},
>  			{"relative",         no_argument,       NULL, 'r'},
> +			{"resolution",       no_argument,       NULL, 'R'},
>  			{"system",           no_argument,       NULL, 's'},
>  			{"smp",              no_argument,       NULL, 'S'},
>  			{"threads",          optional_argument, NULL, 't'},
> @@ -1085,11 +1092,12 @@ static void process_options (int argc, c
>  			{"verbose",          no_argument,       NULL, 'v'},
>  			{"wakeup",           no_argument,       NULL, 'w'},
>  			{"wakeuprt",         no_argument,       NULL, 'W'},
> +			{"dbg_cyclictest",   no_argument,       NULL, 'X'},
>  			{"policy",           required_argument, NULL, 'y'},
>  			{"help",             no_argument,       NULL, '?'},
>  			{NULL, 0, NULL, 0}
>  		};
> -		int c = getopt_long(argc, argv, "a::b:Bc:Cd:D:e:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:",
> +		int c = getopt_long(argc, argv, "a::b:Bc:Cd:D:e:Efh:H:i:Il:MnNo:O:p:PmqQrRsSt::uUvD:wWXT:y:",
>  				    long_options, &option_index);
>  		if (c == -1)
>  			break;
> @@ -1158,6 +1166,7 @@ static void process_options (int argc, c
>  		case 'q': quiet = 1; break;
>  		case 'Q': priospread = 1; break;
>  		case 'r': timermode = TIMER_RELTIME; break;
> +		case 'R': check_clock_resolution = 1; break;
>  		case 's': use_system = MODE_SYS_OFFSET; break;
>  		case 'S':  /* SMP testing */
>  			if (numa)
> @@ -1202,6 +1211,7 @@ static void process_options (int argc, c
>  		case 'v': verbose = 1; break;
>  		case 'w': tracetype = WAKEUP; break;
>  		case 'W': tracetype = WAKEUPRT; break;
> +		case 'X': ct_debug = 1; break;
>  		case 'y': handlepolicy(optarg); break;
>  
>  		case '?': display_help(0); break;
> @@ -1483,6 +1493,104 @@ int main(int argc, char **argv)
>  	if (check_timer())
>  		warn("High resolution timers not available\n");
>  
> +	if (check_clock_resolution) {
> +		int clock;
> +		uint64_t diff;
> +		int k;
> +		uint64_t min_non_zero_diff = UINT64_MAX;
> +		struct timespec now;
> +		struct timespec prev;
> +		uint64_t reported_resolution = UINT64_MAX;
> +		struct timespec res;
> +		struct timespec *time;
> +		int times;
> +		int zero_diff = 0;
> +
> +		clock = clocksources[clocksel];
> +
> +		if (clock_getres(clock, &res)) {
> +			warn("clock_getres failed");
> +		} else {
> +			reported_resolution = (NSEC_PER_SEC * res.tv_sec) + res.tv_nsec;
> +		}
> +
> +
> +		/*
> +		 * Calculate how many calls to clock_gettime are needed.
> +		 * Then call it that many times.
> +		 * Goal is to collect timestamps for ~ 0.001 sec.
> +		 * This will reliably capture resolution <= 500 usec.
> +		 */
> +		times = 1000;
> +		clock_gettime(clock, &prev);
> +		for (k=0; k < times; k++) {
> +			clock_gettime(clock, &now);
> +		}
> +
> +		diff = calcdiff_ns(now, prev);
> +		if (diff == 0) {
> +			/*
> +			 * No clock rollover occurred.
> +			 * Use the default value for times.
> +			 */
> +			times = -1;
> +		} else {
> +			int call_time;
> +			call_time = diff / times;         /* duration 1 call */
> +			times = NSEC_PER_SEC / call_time; /* calls per second */
> +			times /= 1000;                    /* calls per msec */
> +			if (times < 1000)
> +				times = 1000;
> +		}
> +		/* sanity check */
> +		if ((times <= 0) || (times > 100000))
> +			times = 100000;
> +
> +		time = calloc(times, sizeof(*time));
> +
> +		for (k=0; k < times; k++) {
> +			clock_gettime(clock, &time[k]);
> +		}
> +
> +		if (ct_debug) {
> +			fprintf(stderr, "\n\nFor %d consecutive calls to clock_gettime():\n\n", times);
> +			fprintf(stderr, "time, delta time (nsec)\n\n");
> +		}
> +
> +		prev = time[0];
> +		for (k=1; k < times; k++) {
> +
> +			diff = calcdiff_ns(time[k], prev);
> +			prev = time[k];
> +
> +			if (diff == 0) {
> +				zero_diff = 1;
> +			} else if (diff < min_non_zero_diff) {
> +				min_non_zero_diff = diff;
> +			}
> +
> +			if (ct_debug)
> +				fprintf(stderr, "%ld.%06ld  %5llu\n", time[k].tv_sec, time[k].tv_nsec, diff);
> +		}
> +
> +		free(time);
> +
> +
> +		if (verbose ||
> +		    (min_non_zero_diff && (min_non_zero_diff > reported_resolution))) {
> +		    	/*
> +			 * Measured clock resolution includes the time to call
> +			 * clock_gettime(), so it will be slightly larger than
> +			 * actual resolution.
> +			 */
> +			fprintf(stderr, "reported clock resolution: %lld nsec\n",
> +				reported_resolution);
> +			fprintf(stderr, "measured clock resolution approximately: %llu nsec\n",
> +				min_non_zero_diff);
> +		}
> +
> +	}
> +
>  	mode = use_nanosleep + use_system;
>  
>  	sigemptyset(&sigset);
> 
> --

I've tested it and it seems okay on the whole.

A few comments. Could you use the src/lib/error.c functions instead of 
fprintf?

Also there are a few compile warnings, you're probably not compiling on 
64-bits?

src/cyclictest/cyclictest.c:1573: warning: format ‘%5llu’ expects type 
‘long long unsigned int’, but argument 5 has type ‘uint64_t’
src/cyclictest/cyclictest.c:1587: warning: format ‘%lld’ expects type 
‘long long int’, but argument 3 has type ‘uint64_t’
src/cyclictest/cyclictest.c:1589: warning: format ‘%llu’ expects type 
‘long long unsigned int’, but argument 3 has type ‘uint64_t’

Could you please fix those up?

Also, there is some slightly funky formatting for 80-char screens. Not 
sure how much other's care about it.

Thanks

John

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-05-15 22:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-11  0:59 [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters Frank Rowand
2012-05-11  1:02 ` [PATCH 1/2] V2: cyclictest: report large measured clock latency Frank Rowand
2012-05-15 22:08   ` John Kacur
2012-05-15 22:03 ` [PATCH 1/2] V2: cyclictest: clean up getopt_long() parameters John Kacur

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.