Hi, This patch converts the testcase rt-migrate-test.c to the coding format used by the other realtime testcases in LTP, by making use of the librttest and libstats infrastructure.
Signed-off-by: Kiran Prakash <[email protected]> Acked-by: Darren Hart <[email protected]> Acked-by: Sripathi Kodi <[email protected]> --- rt-migrate-test_orig.c 2009-08-11 16:36:21.000000000 +0530 +++ rt-migrate-test.c 2009-08-17 17:20:45.000000000 +0530 @@ -1,5 +1,5 @@ -/* - * rt-migrate-test.c + +/****************************************************************************** * * Copyright (C) 2007-2009 Steven Rostedt <[email protected]> * @@ -18,7 +18,33 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * NAME + * rt-migrate-test.c + * + * DESCRIPTION + * This test makes sure that all the high prio tasks that are in the + * running state are actually running on a CPU if it can. + ** Steps: + * - Creates N+1 threads with lower real time priorities. + * Where N is the number of CPUs in the system. + * - If the thread is high priority, and if a CPU is available, the + * thread runs on that CPU. + * - The thread records the start time and the number of ticks in the run + * interval. + * - The output indicates if lower prio task is quicker than higher + * priority task. + * + * USAGE: + * Use run_auto.sh in the current directory to build and run the test. + * + * AUTHOR + * Steven Rostedt <[email protected]> + * + * HISTORY + * 30 July, 2009: Initial version by Steven Rostedt + * 11 Aug, 2009: Converted the coding style to the one used by the realtime + * testcases by Kiran Prakash + * */ #define _GNU_SOURCE #include <stdio.h> @@ -42,14 +68,17 @@ #include <errno.h> #include <sched.h> #include <pthread.h> +#include <librttest.h> +#include <libstats.h> #define gettid() syscall(__NR_gettid) -#define VERSION_STRING "V 0.3" +#define VERSION_STRING "V 0.4LTP" int nr_tasks; int lfd; +int numcpus; static int mark_fd = -1; static __thread char buff[BUFSIZ+1]; @@ -90,18 +119,12 @@ static void ftrace_write(const char *fmt write(mark_fd, buff, n); } -#define nano2sec(nan) (nan / 1000000000ULL) -#define nano2ms(nan) (nan / 1000000ULL) -#define nano2usec(nan) (nan / 1000ULL) -#define usec2nano(sec) (sec * 1000ULL) -#define ms2nano(ms) (ms * 1000000ULL) -#define sec2nano(sec) (sec * 1000000000ULL) -#define INTERVAL ms2nano(100ULL) -#define RUN_INTERVAL ms2nano(20ULL) +#define INTERVAL 100ULL * NS_PER_MS +#define RUN_INTERVAL 20ULL * NS_PER_MS #define NR_RUNS 50 #define PRIO_START 2 /* 1 millisec off */ -#define MAX_ERR usec2nano(1000) +#define MAX_ERR 1000 * NS_PER_US #define PROGRESS_CHARS 70 @@ -110,7 +133,7 @@ static unsigned long long run_interval = static unsigned long long max_err = MAX_ERR; static int nr_runs = NR_RUNS; static int prio_start = PRIO_START; -static int check; +static int check = 1; static int stop; static unsigned long long now; @@ -120,26 +143,11 @@ static int loop; static pthread_barrier_t start_barrier; static pthread_barrier_t end_barrier; -static unsigned long long **intervals; -static unsigned long long **intervals_length; -static unsigned long **intervals_loops; +stats_container_t *intervals; +stats_container_t *intervals_length; +stats_container_t *intervals_loops; static long *thread_pids; -static char buffer[BUFSIZ]; - -static void perr(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vsnprintf(buffer, BUFSIZ, fmt, ap); - va_end(ap); - - perror(buffer); - fflush(stderr); - exit(-1); -} - static void print_progress_bar(int percent) { int i; @@ -151,7 +159,7 @@ static void print_progress_bar(int perce /* Use stderr, so we don't capture it */ putc('\r', stderr); putc('|', stderr); - for (i=0; i < PROGRESS_CHARS; i++) + for (i = 0; i < PROGRESS_CHARS; i++) putc(' ', stderr); putc('|', stderr); putc('\r', stderr); @@ -159,97 +167,59 @@ static void print_progress_bar(int perce p = PROGRESS_CHARS * percent / 100; - for (i=0; i < p; i++) + for (i = 0; i < p; i++) putc('-', stderr); fflush(stderr); } -static void usage(char **argv) +static void usage() { - char *arg = argv[0]; - char *p = arg+strlen(arg); - - while (p >= arg && *p != '/') - p--; - p++; - - printf("%s %s\n", p, VERSION_STRING); + rt_help(); printf("Usage:\n" - "%s <options> nr_tasks\n\n" - "-p prio --prio prio base priority to start RT tasks with (2) \n" - "-r time --run-time time Run time (ms) to busy loop the threads (20)\n" - "-s time --sleep-time time Sleep time (ms) between intervals (100)\n" - "-m time --maxerr time Max allowed error (microsecs)\n" - "-l loops --loops loops Number of iterations to run (50)\n" - "-c --check Stop if lower prio task is quick than higher (off)\n" - " () above are defaults \n", - p); - exit(0); -} - -static void parse_options (int argc, char *argv[]) -{ - for (;;) { - int option_index = 0; - /** Options for getopt */ - static struct option long_options[] = { - {"prio", required_argument, NULL, 'p'}, - {"run-time", required_argument, NULL, 'r'}, - {"sleep-time", required_argument, NULL, 's'}, - {"maxerr", required_argument, NULL, 'm'}, - {"loops", required_argument, NULL, 'l'}, - {"check", no_argument, NULL, 'c'}, - {"help", no_argument, NULL, '?'}, - {NULL, 0, NULL, 0} - }; - int c = getopt_long (argc, argv, "p:r:s:m:l:ch", - long_options, &option_index); - if (c == -1) - break; + "-a priority Priority of the threads" + "-r time Run time (ms) to busy loop the threads (20)\n" + "-t time Sleep time (ms) between intervals (100)\n" + "-e time Max allowed error (microsecs)\n" + "-l loops Number of iterations to run (50)\n" + ); +} + +static void parse_args(int c, char *v) +{ switch (c) { - case 'p': prio_start = atoi(optarg); break; + case 'a': prio_start = atoi(v); break; case 'r': - run_interval = atoi(optarg); + run_interval = atoi(v); break; - case 's': interval = atoi(optarg); break; - case 'l': nr_runs = atoi(optarg); break; - case 'm': max_err = usec2nano(atoi(optarg)); break; - case 'c': check = 1; break; + case 't': interval = atoi(v); break; + case 'l': nr_runs = atoi(v); break; + case 'e': max_err = atoi(v) * NS_PER_US; break; case '?': case 'h': - usage(argv); - break; + usage(); + exit(0); } - } - -} - -static unsigned long long get_time(void) -{ - struct timeval tv; - unsigned long long time; - - gettimeofday(&tv, NULL); - - time = sec2nano(tv.tv_sec); - time += usec2nano(tv.tv_usec); - - return time; } static void record_time(int id, unsigned long long time, unsigned long l) { unsigned long long ltime; - + stats_record_t rec; if (loop >= nr_runs) return; time -= now; - ltime = get_time(); + ltime = rt_gettime() / NS_PER_US; ltime -= now; - intervals[loop][id] = time; - intervals_length[loop][id] = ltime; - intervals_loops[loop][id] = l; + rec.x = loop; + rec.y = time; + stats_container_append(&intervals[id], rec); + rec.x = loop; + rec.y = ltime; + stats_container_append(&intervals_length[id], rec); + rec.x = loop; + rec.y = l; + stats_container_append(&intervals_loops[id], rec); } static void print_results(void) @@ -269,32 +239,26 @@ static void print_results(void) printf("%6d ", t); printf("\n"); - for (i=0; i < nr_runs; i++) { + for (t = 0; t < nr_tasks; t++) { + tasks_max[t] = stats_max(&intervals[t]); + tasks_min[t] = stats_min(&intervals[t]); + tasks_avg[t] = stats_avg(&intervals[t]); + } + for (i = 0; i < nr_runs; i++) { printf("%4d: ", i); - for (t=0; t < nr_tasks; t++) { - unsigned long long itv = intervals[i][t]; + for (t = 0; t < nr_tasks; t++) + printf("%6lld ", intervals[t].records[i].y); - if (tasks_max[t] < itv) - tasks_max[t] = itv; - if (tasks_min[t] > itv) - tasks_min[t] = itv; - tasks_avg[t] += itv; - printf("%6lld ", nano2usec(itv)); - } printf("\n"); printf(" len: "); - for (t=0; t < nr_tasks; t++) { - unsigned long long len = intervals_length[i][t]; + for (t = 0; t < nr_tasks; t++) + printf("%6lld ", intervals_length[t].records[i].y); - printf("%6lld ", nano2usec(len)); - } printf("\n"); printf(" loops: "); - for (t=0; t < nr_tasks; t++) { - unsigned long loops = intervals_loops[i][t]; + for (t = 0; t < nr_tasks; t++) + printf("%6ld ", intervals_loops[t].records[i].y); - printf("%6ld ", loops); - } printf("\n"); printf("\n"); } @@ -304,19 +268,14 @@ static void print_results(void) for (t=0; t < nr_tasks; t++) { printf(" Task %d (prio %d) (pid %ld):\n", t, t + prio_start, thread_pids[t]); - printf(" Max: %lld us\n", nano2usec(tasks_max[t])); - printf(" Min: %lld us\n", nano2usec(tasks_min[t])); - printf(" Tot: %lld us\n", nano2usec(tasks_avg[t])); - printf(" Avg: %lld us\n", nano2usec(tasks_avg[t] / nr_runs)); + printf(" Max: %lld us\n", tasks_max[t]); + printf(" Min: %lld us\n", tasks_min[t]); + printf(" Tot: %lld us\n", tasks_avg[t] * nr_runs); + printf(" Avg: %lld us\n", tasks_avg[t]); printf("\n"); } - if (check) { - if (check < 0) - printf(" Failed!\n"); - else - printf(" Passed!\n"); - } + printf(" Result: %s\n", (check < 0) ? "FAIL" : "PASS"); } static unsigned long busy_loop(unsigned long long start_time) @@ -326,7 +285,7 @@ static unsigned long busy_loop(unsigned do { l++; - time = get_time(); + time = rt_gettime(); } while ((time - start_time) < RUN_INTERVAL); return l; @@ -334,11 +293,10 @@ static unsigned long busy_loop(unsigned void *start_task(void *data) { - long id = (long)data; + struct thread *thr = (struct thread *)data; + long id = (long) thr->arg; + thread_pids[id] = gettid(); unsigned long long start_time; - struct sched_param param = { - .sched_priority = id + prio_start, - }; int ret; int high = 0; cpu_set_t cpumask; @@ -349,7 +307,7 @@ void *start_task(void *data) ret = sched_getaffinity(0, sizeof(save_cpumask), &save_cpumask); if (ret < 0) - perr("getting affinity"); + debug(DBG_ERR, "sched_getaffinity failed: %s\n", strerror(ret)); pid = gettid(); @@ -357,10 +315,6 @@ void *start_task(void *data) if (id == nr_tasks-1) high = 1; - ret = sched_setscheduler(0, SCHED_FIFO, ¶m); - if (ret < 0 && !id) - fprintf(stderr, "Warning, can't set priorities\n"); - while (!done) { if (high) { /* rotate around the CPUS */ @@ -371,11 +325,11 @@ void *start_task(void *data) sched_setaffinity(0, sizeof(cpumask), &cpumask); } pthread_barrier_wait(&start_barrier); - start_time = get_time(); + start_time = rt_gettime(); ftrace_write("Thread %d: started %lld diff %lld\n", pid, start_time, start_time - now); l = busy_loop(start_time); - record_time(id, start_time, l); + record_time(id, start_time / NS_PER_US, l); pthread_barrier_wait(&end_barrier); } @@ -389,26 +343,27 @@ static int check_times(int l) unsigned long long last_loops; unsigned long long last_length; - for (i=0; i < nr_tasks; i++) { - if (i && last < intervals[l][i] && - ((intervals[l][i] - last) > max_err)) { + for (i = 0; i < nr_tasks; i++) { + if (i && last < intervals[i].records[l].y && + ((intervals[i].records[l].y - last) > max_err)) { /* * May be a false positive. * Make sure that we did more loops * our start is before the end * and the end should be tested. */ - if (intervals_loops[l][i] < last_loops || - intervals[l][i] > last_length || - (intervals_length[l][i] > last_length && - intervals_length[l][i] - last_length > max_err)) { + if (intervals_loops[i].records[l].y < last_loops || + intervals[i].records[l].y > last_length || + (intervals_length[i].records[l].y > last_length && + intervals_length[i].records[l].y - last_length > + max_err)) { check = -1; return 1; } } - last = intervals[l][i]; - last_loops = intervals_loops[l][i]; - last_length = intervals_length[l][i]; + last = intervals[i].records[l].y; + last_loops = intervals_loops[i].records[l].y; + last_length = intervals_length[i].records[l].y; } return 0; } @@ -418,39 +373,6 @@ static void stop_log(int sig) stop = 1; } -static int count_cpus(void) -{ - FILE *fp; - char buf[1024]; - int cpus = 0; - char *pbuf; - size_t *pn; - size_t n; - int r; - - n = 1024; - pn = &n; - pbuf = buf; - - fp = fopen("/proc/cpuinfo", "r"); - if (!fp) - perr("Can not read cpuinfo"); - - while ((r = getline(&pbuf, pn, fp)) >= 0) { - char *p; - - if (strncmp(buf, "processor", 9) != 0) - continue; - for (p = buf+9; isspace(*p); p++) - ; - if (*p == ':') - cpus++; - } - fclose(fp); - - return cpus; -} - int main (int argc, char **argv) { pthread_t *threads; @@ -459,62 +381,56 @@ int main (int argc, char **argv) struct timespec intv; struct sched_param param; - parse_options(argc, argv); - + rt_init("a:r:t:e:l:h:", parse_args, argc, argv); signal(SIGINT, stop_log); if (argc >= (optind + 1)) nr_tasks = atoi(argv[optind]); - else - nr_tasks = count_cpus() + 1; + else { + numcpus = sysconf(_SC_NPROCESSORS_ONLN); + nr_tasks = numcpus + 1; + } + + intervals = malloc(sizeof(stats_container_t) * nr_tasks); + if (!intervals) + debug(DBG_ERR, "malloc failed\n"); + memset(intervals, 0, sizeof(stats_container_t) * nr_tasks); + + intervals_length = malloc(sizeof(stats_container_t) * nr_tasks); + if (!intervals_length) + debug(DBG_ERR, "malloc failed\n"); + memset(intervals_length, 0, sizeof(stats_container_t) * nr_tasks); + + if (!intervals_loops) + debug(DBG_ERR, "malloc failed\n"); + intervals_loops = malloc(sizeof(stats_container_t) * nr_tasks); + memset(intervals_loops, 0, sizeof(stats_container_t) * nr_tasks); threads = malloc(sizeof(*threads) * nr_tasks); if (!threads) - perr("malloc"); + debug(DBG_ERR, "malloc failed\n"); memset(threads, 0, sizeof(*threads) * nr_tasks); ret = pthread_barrier_init(&start_barrier, NULL, nr_tasks + 1); ret = pthread_barrier_init(&end_barrier, NULL, nr_tasks + 1); if (ret < 0) - perr("pthread_barrier_init"); + debug(DBG_ERR, "pthread_barrier_init failed: %s\n", + strerror(ret)); - intervals = malloc(sizeof(void*) * nr_runs); - if (!intervals) - perr("malloc intervals array"); - - intervals_length = malloc(sizeof(void*) * nr_runs); - if (!intervals_length) - perr("malloc intervals length array"); - intervals_loops = malloc(sizeof(void*) * nr_runs); - if (!intervals_loops) - perr("malloc intervals loops array"); + for (i = 0; i < nr_tasks; i++) { + stats_container_init(&intervals[i], nr_runs); + stats_container_init(&intervals_length[i], nr_runs); + stats_container_init(&intervals_loops[i], nr_runs); + } thread_pids = malloc(sizeof(long) * nr_tasks); if (!thread_pids) - perr("malloc thread_pids"); - - for (i=0; i < nr_runs; i++) { - intervals[i] = malloc(sizeof(unsigned long long)*nr_tasks); - if (!intervals[i]) - perr("malloc intervals"); - memset(intervals[i], 0, sizeof(unsigned long long)*nr_tasks); - - intervals_length[i] = malloc(sizeof(unsigned long long)*nr_tasks); - if (!intervals_length[i]) - perr("malloc length intervals"); - memset(intervals_length[i], 0, sizeof(unsigned long long)*nr_tasks); - - intervals_loops[i] = malloc(sizeof(unsigned long)*nr_tasks); - if (!intervals_loops[i]) - perr("malloc loops intervals"); - memset(intervals_loops[i], 0, sizeof(unsigned long)*nr_tasks); - } - - for (i=0; i < nr_tasks; i++) { - if (pthread_create(&threads[i], NULL, start_task, (void *)i)) - perr("pthread_create"); + debug(DBG_ERR, "malloc thread_pids failed\n"); + for (i = 0; i < nr_tasks; i++) { + threads[i] = create_fifo_thread(start_task, (void *)i, + prio_start + i); } /* @@ -528,12 +444,10 @@ int main (int argc, char **argv) memset(¶m, 0, sizeof(param)); param.sched_priority = nr_tasks + prio_start; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) - fprintf(stderr, "Warning, can't set priority of main thread!\n"); - - - - intv.tv_sec = nano2sec(INTERVAL); - intv.tv_nsec = INTERVAL % sec2nano(1); + debug(DBG_WARN, "Warning, can't set priority of" + "main thread !\n"); + intv.tv_sec = INTERVAL / NS_PER_SEC; + intv.tv_nsec = INTERVAL % (1 * NS_PER_SEC); print_progress_bar(0); @@ -542,7 +456,7 @@ int main (int argc, char **argv) for (loop=0; loop < nr_runs; loop++) { unsigned long long end; - now = get_time(); + now = rt_gettime() / NS_PER_US; ftrace_write("Loop %d now=%lld\n", loop, now); @@ -550,14 +464,12 @@ int main (int argc, char **argv) ftrace_write("All running!!!\n"); - nanosleep(&intv, NULL); - + rt_nanosleep(intv.tv_nsec); print_progress_bar((loop * 100)/ nr_runs); - end = get_time(); + end = rt_gettime() / NS_PER_US; ftrace_write("Loop %d end now=%lld diff=%lld\n", loop, end, end - now); - - pthread_barrier_wait(&end_barrier); + ret = pthread_barrier_wait(&end_barrier); if (stop || (check && check_times(loop))) { loop++; @@ -571,9 +483,7 @@ int main (int argc, char **argv) done = 1; pthread_barrier_wait(&end_barrier); - for (i=0; i < nr_tasks; i++) - pthread_join(threads[i], (void*)&thread_pids[i]); - + join_threads(); print_results(); if (stop) { ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
