diff options
Diffstat (limited to 'src/cyclictest/cyclictest.c')
-rw-r--r-- | src/cyclictest/cyclictest.c | 121 |
1 files changed, 116 insertions, 5 deletions
diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c index b53fb27..f5a67dc 100644 --- a/src/cyclictest/cyclictest.c +++ b/src/cyclictest/cyclictest.c @@ -166,6 +166,29 @@ struct thread_stat { long num_outliers; }; +static pthread_mutex_t trigger_lock = PTHREAD_MUTEX_INITIALIZER; + +static int trigger = 0; /* Record spikes > trigger, 0 means don't record */ +static int trigger_list_size = 1024; /* Number of list nodes */ + +/* Info to store when the diff is greater than the trigger */ +struct thread_trigger { + int cpu; + int tnum; /* thread number */ + int64_t ts; /* time-stamp */ + int diff; + struct thread_trigger *next; +}; + +struct thread_trigger *head = NULL; +struct thread_trigger *tail = NULL; +struct thread_trigger *current = NULL; +static int spikes; /* count of the number of spikes */ + +static int trigger_init(); +static void trigger_print(); +static void trigger_update(struct thread_param *par, int diff, int64_t ts); + static int shutdown; static int tracelimit = 0; static int notrace = 0; @@ -396,6 +419,14 @@ static inline int64_t calcdiff_ns(struct timespec t1, struct timespec t2) return diff; } +static inline int64_t calctime(struct timespec t) +{ + int64_t time; + time = USEC_PER_SEC * t.tv_sec; + time += ((int) t.tv_nsec) / 1000; + return time; +} + static void traceopt(char *option) { char *ptr; @@ -939,6 +970,10 @@ static void *timerthread(void *param) } stat->avg += (double) diff; + if (trigger && (diff > trigger)) { + trigger_update(par, diff, calctime(now)); + } + if (duration && (calcdiff(now, stop) >= 0)) shutdown++; @@ -1088,6 +1123,9 @@ static void display_help(int error) "-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" + " --spike=trigger record all spikes > trigger\n" + " --spike-nodes these are the number of spikes we can record\n" + " the default is 1024 if not specified\n" "-t --threads one thread per available processor\n" "-t [NUM] --threads=NUM number of threads:\n" " without NUM, threads = max_cpus\n" @@ -1228,11 +1266,12 @@ enum option_values { OPT_AFFINITY=1, OPT_NOTRACE, OPT_BREAKTRACE, OPT_PREEMPTIRQ, OPT_CLOCK, OPT_CONTEXT, OPT_DISTANCE, OPT_DURATION, OPT_LATENCY, OPT_EVENT, OPT_FTRACE, OPT_FIFO, OPT_HISTOGRAM, OPT_HISTOFALL, OPT_HISTFILE, - OPT_INTERVAL, OPT_IRQSOFF, OPT_LOOPS, OPT_MLOCKALL, OPT_REFRESH, OPT_NANOSLEEP, - OPT_NSECS, OPT_OSCOPE, OPT_TRACEOPT, OPT_PRIORITY, OPT_PREEMPTOFF, 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_INTERVAL, OPT_IRQSOFF, OPT_LOOPS, OPT_MLOCKALL, OPT_REFRESH, + OPT_NANOSLEEP, OPT_NSECS, OPT_OSCOPE, OPT_TRACEOPT, OPT_PRIORITY, + OPT_PREEMPTOFF, OPT_QUIET, OPT_PRIOSPREAD, OPT_RELATIVE, OPT_RESOLUTION, + OPT_SYSTEM, OPT_SMP, OPT_THREADS, OPT_TRACER, OPT_TRIGGER, + OPT_TRIGGER_NODES, OPT_UNBUFFERED, OPT_NUMA, OPT_VERBOSE, OPT_WAKEUP, + OPT_WAKEUPRT, OPT_DBGCYCLIC, OPT_POLICY, OPT_HELP, OPT_NUMOPTS, OPT_ALIGNED, OPT_SECALIGNED, OPT_LAPTOP, }; @@ -1284,6 +1323,8 @@ static void process_options (int argc, char *argv[], int max_cpus) {"secaligned", optional_argument, NULL, OPT_SECALIGNED }, {"system", no_argument, NULL, OPT_SYSTEM }, {"smp", no_argument, NULL, OPT_SMP }, + {"spike", required_argument, NULL, OPT_TRIGGER }, + {"spike-nodes", required_argument, NULL, OPT_TRIGGER_NODES }, {"threads", optional_argument, NULL, OPT_THREADS }, {"tracer", required_argument, NULL, OPT_TRACER }, {"unbuffered", no_argument, NULL, OPT_UNBUFFERED }, @@ -1459,6 +1500,13 @@ static void process_options (int argc, char *argv[], int max_cpus) else num_threads = max_cpus; break; + case OPT_TRIGGER: + trigger = atoi(optarg); + break; + case OPT_TRIGGER_NODES: + if (trigger) + trigger_list_size = atoi(optarg); + break; case 'T': case OPT_TRACER: tracetype = CUSTOM; @@ -1825,6 +1873,58 @@ static void *fifothread(void *param) return NULL; } +static int trigger_init() +{ + int i; + int size = trigger_list_size; + struct thread_trigger *trig = NULL; + for(i=0; i<size; i++) { + trig = malloc(sizeof(struct thread_trigger)); + if (trig != NULL) { + if (head == NULL) { + head = trig; + tail = trig; + } else { + tail->next = trig; + tail = trig; + } + trig->tnum = i; + trig->next = NULL; + } else { + return -1; + } + } + current = head; + return 0; +} + +static void trigger_print() +{ + struct thread_trigger *trig = head; + char *fmt = "T:%2d Spike:%8ld: TS: %12ld\n"; + + if (current == head) return; + printf("\n"); + while (trig->next != current) { + fprintf(stdout, fmt, trig->tnum, trig->diff, trig->ts); + trig = trig->next; + } + fprintf(stdout, fmt, trig->tnum, trig->diff, trig->ts); + printf("spikes = %d\n\n", spikes); +} + +static void trigger_update(struct thread_param *par, int diff, int64_t ts) +{ + pthread_mutex_lock(&trigger_lock); + if (current != NULL) { + current->tnum = par->tnum; + current->ts = ts; + current->diff = diff; + current = current->next; + } + spikes++; + pthread_mutex_unlock(&trigger_lock); +} int main(int argc, char **argv) { @@ -1843,6 +1943,14 @@ int main(int argc, char **argv) if (verbose) printf("Max CPUs = %d\n", max_cpus); + if (trigger) { + int retval; + retval = trigger_init(); + if (retval != 0) { + fprintf(stderr, "trigger_init() failed\n"); + exit(EXIT_FAILURE); + } + } /* lock all memory (prevent swapping) */ if (lockall) @@ -2161,6 +2269,9 @@ int main(int argc, char **argv) threadfree(statistics[i]->values, VALBUF_SIZE*sizeof(long), parameters[i]->node); } + if (trigger) + trigger_print(); + if (histogram) { print_hist(parameters, num_threads); for (i = 0; i < num_threads; i++) { |