diff options
-rw-r--r-- | src/cyclictest/cyclictest.8 | 11 | ||||
-rw-r--r-- | src/cyclictest/cyclictest.c | 39 |
2 files changed, 44 insertions, 6 deletions
diff --git a/src/cyclictest/cyclictest.8 b/src/cyclictest/cyclictest.8 index fbb6174..60102df 100644 --- a/src/cyclictest/cyclictest.8 +++ b/src/cyclictest/cyclictest.8 @@ -16,7 +16,7 @@ cyclictest \- High resolution test program .SH SYNOPSIS .B cyclictest -.RI "[ \-hfmnqrsvMS ] [\-a " proc " ] [\-b " usec " ] [\-c " clock " ] [\-d " dist " ] \ +.RI "[ \-hfmnqrsvMS ] [\-a " proc " ] [\-A " align " ] [\-b " usec " ] [\-c " clock " ] [\-d " dist " ] \ [\-h " histogram " ] [\-i " intv " ] [\-l " loop " ] [\-o " red " ] [\-p " prio " ] \ [\-t " num " ] [\-D " time "] [\-w] [\-W] [\-y " policy " ] [ \-S | \-U ]" @@ -36,6 +36,9 @@ A summary of options is included below. .B \-a, \-\-affinity[=PROC] Run all threads on procesor number PROC. If PROC is not specified, run thread #N on processor #N. .TP +.B \-A, \-\-align=USEC +Align measurement thread wakeups to a specific offset in microseconds +.TP .B \-b, \-\-breaktrace=USEC Send break trace command when latency > USEC. This is a debugging option to control the latency tracer in the realtime preemption patch. It is useful to track down unexpected large latencies on a system. This option does only work with following kernel config options. @@ -149,14 +152,14 @@ where n=task number c=count v=latency value in us. Use this option in combinatio .B \\-D, \-\-duration=TIME Run the test for the specified time, which defaults to seconds. Append 'm', 'h', or 'd' to specify minutes, hours or days .TP -.B \\-w, \-\-wakeup +.B \\-w, \-\-wakeup task wakeup tracing (used with \-b) .TP .B \\-W, \-\-wakeuprt rt-task wakeup tracing (used with \-b) .TP .B \\-y, \-\-policy=NAME -set the scheduler policy of the measurement threads +set the scheduler policy of the measurement threads where NAME is one of: other, normal, batch, idle, fifo, rr .TP .B \\-M, \-\-refresh_on_max @@ -166,7 +169,7 @@ running cyclictest on low-bandwidth connections) .B \\-S, \-\-smp Set options for standard testing on SMP systems. Equivalent to using the options: "\-t \-a \-n" as well keeping any specified priority -equal across all threads +equal across all threads .TP .B \\-U, \-\-numa Similar to the above \-\-smp option, this implies the "\-t \-a \-n" diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c index d0b9dfe..bbdcf93 100644 --- a/src/cyclictest/cyclictest.c +++ b/src/cyclictest/cyclictest.c @@ -140,6 +140,7 @@ struct thread_param { unsigned long interval; int cpu; int node; + int tnum; }; /* Struct for statistics */ @@ -183,6 +184,8 @@ static int check_clock_resolution; static int ct_debug; static int use_fifo = 0; static pthread_t fifo_threadid; +static int aligned = 0; +static int disaligned = 0; static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER; @@ -191,6 +194,10 @@ static pthread_mutex_t break_thread_id_lock = PTHREAD_MUTEX_INITIALIZER; static pid_t break_thread_id = 0; static uint64_t break_thread_value = 0; +static pthread_barrier_t align_barr; +static pthread_barrier_t globalt_barr; +static struct timespec globalt; + /* Backup of kernel variables that we modify */ static struct kvars { char name[KVARNAMELEN]; @@ -768,7 +775,20 @@ void *timerthread(void *param) fatal("timerthread%d: failed to set priority to %d\n", par->cpu, par->prio); /* Get current time */ - clock_gettime(par->clock, &now); + if(aligned){ + pthread_barrier_wait(&globalt_barr); + if(par->tnum==0){ + clock_gettime(par->clock, &globalt); + } + pthread_barrier_wait(&align_barr); + now = globalt; + if(disaligned){ + now.tv_nsec += disaligned * par->tnum; + tsnorm(&now); + } + } + else + clock_gettime(par->clock, &now); next = now; next.tv_sec += interval.tv_sec; @@ -958,6 +978,7 @@ static void display_help(int error) "cyclictest <options>\n\n" "-a [NUM] --affinity run thread #N on processor #N, if possible\n" " with NUM pin all threads to the processor NUM\n" + "-A USEC --aligned=USEC align thread wakeups to a specific offset\n" "-b USEC --breaktrace=USEC send break trace command when latency > USEC\n" "-B --preemptirqs both preempt and irqsoff tracing (used with -b)\n" "-c CLOCK --clock=CLOCK select clock\n" @@ -1095,6 +1116,7 @@ enum option_values { OPT_QUIET, OPT_PRIOSPREAD, OPT_RELATIVE, OPT_RESOLUTION, OPT_SYSTEM, OPT_SMP, OPT_THREADS, OPT_TRACER, OPT_UNBUFFERED, OPT_NUMA, OPT_VERBOSE, OPT_WAKEUP, OPT_WAKEUPRT, OPT_DBGCYCLIC, OPT_POLICY, OPT_HELP, OPT_NUMOPTS, + OPT_ALIGNED, }; /* Process commandline options */ @@ -1113,6 +1135,7 @@ static void process_options (int argc, char *argv[]) static struct option long_options[] = { {"affinity", optional_argument, NULL, OPT_AFFINITY}, {"notrace", no_argument, NULL, OPT_NOTRACE }, + {"aligned", optional_argument, NULL, OPT_ALIGNED }, {"breaktrace", required_argument, NULL, OPT_BREAKTRACE }, {"preemptirqs", no_argument, NULL, OPT_PREEMPTIRQ }, {"clock", required_argument, NULL, OPT_CLOCK }, @@ -1154,7 +1177,7 @@ static void process_options (int argc, char *argv[]) {"help", no_argument, NULL, OPT_HELP }, {NULL, 0, NULL, 0} }; - int c = getopt_long(argc, argv, "a::b:Bc:Cd:D:Efh:H:i:Il:MnNo:O:p:PmqrRsSt::uUvD:wWT:", + int c = getopt_long(argc, argv, "a::A:b:Bc:Cd:D:Efh:H:i:Il:MnNo:O:p:PmqrRsSt::uUvD:wWT:", long_options, &option_index); if (c == -1) break; @@ -1174,6 +1197,12 @@ static void process_options (int argc, char *argv[]) setaffinity = AFFINITY_USEALL; } break; + case 'A': + case OPT_ALIGNED: + aligned=1; + if (optarg != NULL) + disaligned = atoi(optarg); + break; case 'b': case OPT_BREAKTRACE: tracelimit = atoi(optarg); break; @@ -1413,6 +1442,11 @@ static void process_options (int argc, char *argv[]) if (num_threads < 1) error = 1; + if (aligned) { + pthread_barrier_init (&globalt_barr, NULL, num_threads); + pthread_barrier_init (&align_barr, NULL, num_threads); + } + if (error) display_help(1); } @@ -1889,6 +1923,7 @@ int main(int argc, char **argv) par->max_cycles = max_cycles; par->stats = stat; par->node = node; + par->tnum = i; switch (setaffinity) { case AFFINITY_UNSPECIFIED: par->cpu = -1; break; case AFFINITY_SPECIFIED: par->cpu = affinity; break; |