summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClark Williams <clark.williams@gmail.com>2013-03-13 16:53:53 -0500
committerClark Williams <clark.williams@gmail.com>2013-03-13 16:53:53 -0500
commit1906cc53f5c4e6803cd91403d327c7da272d389a (patch)
tree4679cc8e90c62d91d4fc8bf1fac22f2640a3c114
parent1b92da30837e9552aba209cbdf938877f0fd3bbf (diff)
downloadrt-tests-1906cc53f5c4e6803cd91403d327c7da272d389a.tar.gz
cyclictest: add named fifo for statistics
This code adds the -F/--fifo option to cyclictest. Using the --fifo <path> option will cause cyclictest to create a named fifo at <path> and will dump the current run statistics to that fifo when it is opened an read. Signed-off-by: Clark Williams <clark.williams@gmail.com>
-rw-r--r--src/cyclictest/cyclictest.c90
1 files changed, 79 insertions, 11 deletions
diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
index 0a15dcb..a8f9534 100644
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -1,6 +1,8 @@
/*
* High resolution timer test software
*
+ * (C) 2013 Clark Williams <williams@redhat.com>
+ * (C) 2013 John Kacur <jkacur@redhat.com>
* (C) 2008-2012 Clark Williams <williams@redhat.com>
* (C) 2005-2007 Thomas Gleixner <tglx@linutronix.de>
*
@@ -178,6 +180,8 @@ static int force_sched_other;
static int priospread = 0;
static int check_clock_resolution;
static int ct_debug;
+static int use_fifo = 0;
+static pthread_t fifo_threadid;
static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -195,10 +199,16 @@ static struct kvars {
static char *procfileprefix = "/proc/sys/kernel/";
static char *fileprefix;
static char tracer[MAX_PATH];
+static char fifopath[MAX_PATH];
static char **traceptr;
static int traceopt_count;
static int traceopt_size;
+static struct thread_param **parameters;
+static struct thread_stat **statistics;
+
+static void print_stat(FILE *fp, struct thread_param *par, int index, int verbose, int quiet);
+
static int latency_target_fd = -1;
static int32_t latency_target_value = 0;
@@ -961,6 +971,7 @@ static void display_help(int error)
"-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"
+ "-F --fifo=<path> create a named pipe at path and write stats to it\n"
"-h --histogram=US dump a latency histogram to stdout after the run\n"
" (with same priority about many threads)\n"
" US is the max time to be be tracked in microseconds\n"
@@ -1099,6 +1110,7 @@ static void process_options (int argc, char *argv[])
{"latency", required_argument, NULL, 'e'},
{"event", no_argument, NULL, 'E'},
{"ftrace", no_argument, NULL, 'f'},
+ {"fifo", required_argument, NULL, 'F'},
{"histogram", required_argument, NULL, 'h'},
{"histofall", required_argument, NULL, 'H'},
{"interval", required_argument, NULL, 'i'},
@@ -1163,6 +1175,10 @@ static void process_options (int argc, char *argv[])
break;
case 'E': enable_events = 1; break;
case 'f': tracetype = FUNCTION; ftrace = 1; break;
+ case 'F':
+ use_fifo = 1;
+ strncpy(fifopath, optarg, strlen(optarg));
+ break;
case 'H': histofall = 1; /* fall through */
case 'h': histogram = atoi(optarg); break;
case 'i': interval = atoi(optarg); break;
@@ -1368,6 +1384,19 @@ static int check_timer(void)
static void sighand(int sig)
{
+ if (sig == SIGUSR1) {
+ int i;
+ int oldquiet = quiet;
+
+ quiet = 0;
+ printf("#---------------------------\n");
+ printf("# cyclictest current status:\n");
+ for (i = 0; i < num_threads; i++)
+ print_stat(stdout, parameters[i], i, 0, 0);
+ printf("#---------------------------\n");
+ quiet = oldquiet;
+ return;
+ }
shutdown = 1;
if (refresh_on_max)
pthread_cond_signal(&refresh_on_max_cond);
@@ -1460,7 +1489,7 @@ static void print_hist(struct thread_param *par[], int nthreads)
printf("\n");
}
-static void print_stat(struct thread_param *par, int index, int verbose)
+static void print_stat(FILE *fp, struct thread_param *par, int index, int verbose, int quiet)
{
struct thread_stat *stat = par->stats;
@@ -1473,10 +1502,10 @@ static void print_stat(struct thread_param *par, int index, int verbose)
else
fmt = "T:%2d (%5d) P:%2d I:%ld C:%7lu "
"Min:%7ld Act:%5ld Avg:%5ld Max:%8ld\n";
- printf(fmt, index, stat->tid, par->prio,
- par->interval, stat->cycles, stat->min, stat->act,
- stat->cycles ?
- (long)(stat->avg/stat->cycles) : 0, stat->max);
+ fprintf(fp, fmt, index, stat->tid, par->prio,
+ par->interval, stat->cycles, stat->min, stat->act,
+ stat->cycles ?
+ (long)(stat->avg/stat->cycles) : 0, stat->max);
}
} else {
while (stat->cycles != stat->cyclesread) {
@@ -1488,8 +1517,8 @@ static void print_stat(struct thread_param *par, int index, int verbose)
stat->cycleofmax = stat->cyclesread;
}
if (++stat->reduce == oscope_reduction) {
- printf("%8d:%8lu:%8ld\n", index,
- stat->cycleofmax, stat->redmax);
+ fprintf(fp, "%8d:%8lu:%8ld\n", index,
+ stat->cycleofmax, stat->redmax);
stat->reduce = 0;
stat->redmax = 0;
}
@@ -1498,13 +1527,49 @@ static void print_stat(struct thread_param *par, int index, int verbose)
}
}
+
+/*
+ * thread that creates a named fifo and hands out run stats when someone
+ * reads from the fifo.
+ */
+void *fifothread(void *param)
+{
+ int ret;
+ int fd;
+ FILE *fp;
+ int i;
+
+ if (use_fifo == 0)
+ return NULL;
+
+ unlink(fifopath);
+ ret = mkfifo(fifopath, 0666);
+ if (ret) {
+ fprintf(stderr, "Error creating fifo %s: %s\n", fifopath, strerror(errno));
+ return NULL;
+ }
+ while (!shutdown) {
+ fd = open(fifopath, O_WRONLY|O_NONBLOCK);
+ if (fd < 0) {
+ usleep(500000);
+ continue;
+ }
+ fp = fdopen(fd, "w");
+ for (i=0; i < num_threads; i++)
+ print_stat(fp, parameters[i], i, 0, 0);
+ fclose(fp);
+ usleep(250);
+ }
+ unlink(fifopath);
+ return NULL;
+}
+
+
int main(int argc, char **argv)
{
sigset_t sigset;
int signum = SIGALRM;
int mode;
- struct thread_param **parameters;
- struct thread_stat **statistics;
int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
int i, ret = -1;
int status;
@@ -1642,6 +1707,7 @@ int main(int argc, char **argv)
signal(SIGINT, sighand);
signal(SIGTERM, sighand);
+ signal(SIGUSR1, sighand);
parameters = calloc(num_threads, sizeof(struct thread_param *));
if (!parameters)
@@ -1755,6 +1821,8 @@ int main(int argc, char **argv)
fatal("failed to create thread %d: %s\n", i, strerror(status));
}
+ if (use_fifo)
+ status = pthread_create(&fifo_threadid, NULL, fifothread, NULL);
while (!shutdown) {
char lavg[256];
@@ -1784,7 +1852,7 @@ int main(int argc, char **argv)
for (i = 0; i < num_threads; i++) {
- print_stat(parameters[i], i, verbose);
+ print_stat(stdout, parameters[i], i, verbose, quiet);
if(max_cycles && statistics[i]->cycles >= max_cycles)
allstopped++;
}
@@ -1816,7 +1884,7 @@ int main(int argc, char **argv)
if (statistics[i]->threadstarted) {
pthread_join(statistics[i]->thread, NULL);
if (quiet && !histogram)
- print_stat(parameters[i], i, 0);
+ print_stat(stdout, parameters[i], i, 0, 0);
}
if (statistics[i]->values)
threadfree(statistics[i]->values, VALBUF_SIZE*sizeof(long), parameters[i]->node);