Hey, You did not mention where it should actually go (which directory ?), and how you are integrating the run into the RT tests ?
Regards-- Subrata On Tue, 2009-09-01 at 14:07 +0530, Kiran wrote: > 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 <ki...@linux.vnet.ibm.com> > Acked-by: Darren Hart <dvh...@us.ibm.com> > Acked-by: Sripathi Kodi <sripat...@in.ibm.com> > > --- 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 <srost...@redhat.com> > * > @@ -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 <srost...@redhat.com> > + * > + * 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 > Ltp-list@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/ltp-list ------------------------------------------------------------------------------ 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 Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list