From: Vincent Guittot vincent.guittot@linaro.org
Command line interface is no more supported with new features and the coming new grammars.
Signed-off-by: Vincent Guittot vincent.guittot@linaro.org Signed-off-by: Pi-Cheng Chen pi-cheng.chen@linaro.org --- README.in | 79 +------------ src/rt-app_args.c | 331 +----------------------------------------------------- src/rt-app_args.h | 3 - 3 files changed, 4 insertions(+), 409 deletions(-)
diff --git a/README.in b/README.in index 1883455..0c15e93 100644 --- a/README.in +++ b/README.in @@ -5,8 +5,7 @@ README for rt-app @VERSION@ ==============
rt-app is a test application that starts multiple periodic threads in order to -simulate a real-time periodic load. It supports SCHED_OTHER, SCHED_FIFO, -SCHED_RR as well as the AQuoSA framework and SCHED_DEADLINE. +simulate a real-time periodic load.
Code is currently maintained on GitHub:
@@ -17,16 +16,8 @@ Code is currently maintained on GitHub: REQUIREMENTS ==============
-rt-app runs on GNU/Linux. It needs autoconf, automake, libtool and a recent -compiler (mainly: gcc) for basic features. - -For advanced usage, the following optional libraries are needed: -- qreslib for AQuoSA support (and, obviously a GENS_SCHED patched kernel) -- a SCHED_DEADLINE patched kernel to support SCHED_DEADLINE policy. -- json-c installed for reading config files. In case libjson is not available - for your target, you can download and compile json-c from - http://oss.metaparadigm.com/json-c/ - +rt-app runs on GNU/Linux. It needs autoconf, automake, libtool , json-c and +a recent compiler (mainly: gcc) for basic features.
============= COMPILATION @@ -69,67 +60,3 @@ $ rt-app <config_file> where config file is a full/relative path to a json file (look under doc/ for an example config file) or "-" (without quotes) to read JSON data from stdin.
-OR you can use commandline to define the taskset. -Keep in mind that on commandline it will never be possible to define resources -and how tasks access them. - -$ rt-app -usage: rt-app [options] -t <period>:<exec>[:cpu affinity[:policy[:deadline[:prio]]]] - --h, --help : show this help --f, --fifo : set default policy for threads to SCHED_FIFO --r, --rr : set default policy fior threads to SCHED_RR --s, --spacing : msec to wait beetween thread starts --l, --logdir : save logs to different directory --b, --baselog : basename for logs (implies -l . if not set) --G, --gnuplot : generate gnuplot script (needs -l) --D, --duration : time (in seconds) before stopping threads --K, --no-mlock : Do not lock pages in memory --q, --qos : create AQuoSA reservation --g, --frag : fragment for the reservation - -POLICY: f=SCHED_FIFO, r=SCHED_RR, o=SCHED_OTHER, q=AQuoSA -AFFINITY: comma-separated cpu index (starting from 0) i.e. 0,2,3 for first, -third and fourth CPU - -Note: when using AQuoSA scheduling, priority is used as percent increment for -budget over exec time - -Options: - -* --fifo,--rr and --qos sets the default scheduling policy for all threads. - --qos is available only when compiled with AQuoSA support enabled. - -* --logdir and --baselog control log output (rt-app creates one log for each - thread). If --logdir is not present, rt-app logs everything to stdout. - When logging to file and -D (see below) is present, the file is written - at the end of execution, during which all logging data is kept in - memory. - -* --gnuplot if it is present then rt-app outputs sample gnuplot scripts to - $logdir (which must be passed too - -* --spacing and --duration control the spacing between threads and their - duration of execution, i.e. each thread is started every $spacing ms - and the total runtime is $duration. - -* --frag (AQuoSA only): fragments the reservation period by $fragmentation, i.e. - reservation period is $frag times smaller than thread's period. - -* --no-mlock: do not lock threads' memory pages when using realtime scheduling - classes - -Each thread is specified by - - --thread <period>:<exec>[:$POLICY[:deadline[:prio]]]: - -period : thread period in microseconds -exec : thread WCET in microseconds -policy : one of f=SCHED_FIFO, r=SCHED_RR, o=SCHED_OTHER, q=AQuoSA (if enabled) -affinity : comma-separated cpu index (starting from 0) i.e. 0,2,3 for first, - third and fourth CPU -prio : thread priority in SCHED_FIFO/SCHED_RR/SCHED_OTHER, percentile - increment for AQuoSA reservation budget w.r.t. WCET. -deadline : deadline in microseconds (used ONLY for plotting!) - - diff --git a/src/rt-app_args.c b/src/rt-app_args.c index 70783c8..0a83fdd 100644 --- a/src/rt-app_args.c +++ b/src/rt-app_args.c @@ -23,340 +23,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. void usage (const char* msg, int ex_code) { -#ifdef JSON printf("usage:\n" - "rt-app <taskset.json>\nOR\n"); -#endif - printf("rt-app [options] -t <period>:<exec>[:policy" - "[:CPU affinity[:prio[:deadline]]]] -t ...\n\n"); - printf("-h, --help\t\t:\tshow this help\n"); - printf("-f, --fifo\t\t:\tset default policy for threads to SCHED_FIFO\n"); - printf("-r, --rr\t\t:\tset default policy fior threads to SCHED_RR\n"); - printf("-s, --spacing\t\t:\tmsec to wait beetween thread starts\n"); - printf("-l, --logdir\t\t:\tsave logs to different directory\n"); - printf("-b, --baselog\t\t:\tbasename for logs (implies -l . if not set)\n"); - printf("-G, --gnuplot\t\t:\tgenerate gnuplot script (needs -l)\n"); - printf("-D, --duration\t\t:\ttime (in seconds) before stopping threads\n"); - printf("-K, --no-mlock\t\t:\tDo not lock pages in memory\n"); - printf("-T, --ftrace\t\t:\tenable ftrace prints\n"); - printf("-P, --pi_enabled\t:\tenable priority inheritance on resources\n"); - printf("-M, --die_on_dmiss\t:\texit with an error if a task misses a deadline\n"); - -#ifdef AQUOSA - printf("-q, --qos\t:\tcreate AQuoSA reservation\n"); - printf("-g, --frag\t:\tfragment for the reservation\n\n"); -#else -#endif - printf("\nPOLICY: f=SCHED_FIFO, r=SCHED_RR, o=SCHED_OTHER"); -#ifdef DLSCHED - printf(", d=SCHED_DEADLINE"); -#endif -#ifdef AQUOSA - printf(", q=AQuoSA\n"); - printf("when using AQuoSA scheduling, priority is used as" - " percent increment \nfor budget over exec time\n"); -#else - printf("\n"); -#endif - printf("AFFINITY: comma-separated cpu index (starting from 0)\n"); - printf("\ti.e. 0,2,3 for first, third and fourth CPU\n"); + "rt-app <taskset.json>\n");
if (msg != NULL) printf("\n%s\n", msg); exit(ex_code); }
- -void -parse_thread_args(char *arg, int idx, thread_data_t *tdata, policy_t def_policy) -{ - char *str = strdup(arg); - char *token; - long period, exec, dline; - char tmp[256]; - int i = 0; - int cpu; - dline = 0; - - token = strtok(str, ":"); - tdata->name = malloc(sizeof(char) * 5); - tdata->ind = idx; - - /* default name for command line threads */ - snprintf(tdata->name, 1, "t%d", tdata->ind); - tdata->sched_prio = DEFAULT_THREAD_PRIORITY; - tdata->sched_policy = def_policy; - tdata->cpuset = NULL; - tdata->cpuset_str = NULL; - - while ( token != NULL) - { - switch(i) { - case 0: - period = strtol(token, NULL, 10); - if (period <= 0 ) - usage("Cannot set negative period.", - EXIT_INV_COMMANDLINE); - tdata->phases_data->period = usec_to_timespec(period); - i++; - break; - - case 1: - exec = strtol(token,NULL, 10); - //TODO: add support for max_et somehow - if (exec > period) - usage("Exec time cannot be greater than" - " period.", EXIT_INV_COMMANDLINE); - if (exec <= 0 ) - usage("Cannot set negative exec time", - EXIT_INV_COMMANDLINE); - tdata->phases_data->min_et = usec_to_timespec(exec); - tdata->phases_data->max_et = usec_to_timespec(exec); - i++; - break; - - case 2: -#ifdef AQUOSA - if (strcmp(token,"q") == 0) - tdata->sched_policy = aquosa; - else -#endif -#ifdef DLSCHED - if (strcmp(token,"d") == 0) - tdata->sched_policy = deadline; - else -#endif - if (strcmp(token,"f") == 0) - tdata->sched_policy = fifo; - else if (strcmp(token,"r") == 0) - tdata->sched_policy = rr ; - else if (strcmp(token,"o") == 0) - tdata->sched_policy = other; - else { - snprintf(tmp, 256, - "Invalid scheduling policy %s in %s", - token, arg); - usage(tmp, EXIT_INV_COMMANDLINE); - } - policy_to_string(tdata->sched_policy, - tdata->sched_policy_descr); - - i++; - break; - case 3: - if (strcmp(token, "-") == 0) - tdata->cpuset = NULL; - else { - tdata->cpuset = malloc (sizeof(cpu_set_t)); - tdata->cpuset_str = strdup(token); - } - i++; - break; - case 4: - tdata->sched_prio = strtol(token, NULL, 10); - // do not check, will fail in pthread_setschedparam - i++; - break; - case 5: - dline = strtol(token, NULL, 10); - if (dline < exec) - usage("Deadline cannot be less than " - "execution time", EXIT_INV_COMMANDLINE); - if (dline > period) - usage("Deadline cannot be greater than " - "period", EXIT_INV_COMMANDLINE); - if (dline <= 0 ) - usage("Cannot set negative deadline", - EXIT_INV_COMMANDLINE); - tdata->phases_data->deadline = usec_to_timespec(dline); - i++; - break; - } - token = strtok(NULL, ":"); - } - - if ( i < 2 ) { - printf("Period and exec time are mandatory\n"); - exit(EXIT_INV_COMMANDLINE); - } - - if (dline == 0) - tdata->phases_data->deadline = tdata->phases_data->period; - - /* set cpu affinity mask */ - if (tdata->cpuset_str) - { - snprintf(tmp, 256, "%s", tdata->cpuset_str); - token = strtok(tmp, ","); - while (token != NULL && i < 1000) { - cpu = strtol(token, NULL, 10); - CPU_SET(cpu, tdata->cpuset); - strtok(NULL, ","); - i++; - } - } else - tdata->cpuset_str = strdup("-"); - - free(str); -} - -static void -parse_command_line_options(int argc, char **argv, rtapp_options_t *opts) -{ - char tmp[PATH_LENGTH]; - signed char ch; - int longopt_idx; - int i; - - struct stat dirstat; - - /* set defaults */ - opts->spacing = 0; - opts->gnuplot = 0; - opts->lock_pages = 1; - opts->duration = -1; - opts->logbasename = strdup("rt-app"); - opts->logdir = NULL; - opts->nthreads = 0; - opts->ftrace = 0; - opts->die_on_dmiss = 0; - opts->pi_enabled = 0; - opts->policy = other; - opts->threads_data = malloc(sizeof(thread_data_t)); - opts->threads_data->phases_data = malloc(sizeof(phase_data_t)); -#ifdef AQUOSA - opts->fragment = 1; -#endif - - static struct option long_options[] = { - {"help", 0, 0, 'h'}, - {"fifo", 0, 0, 'f'}, - {"rr", 0, 0, 'r'}, - {"thread", 1, 0, 't'}, - {"spacing", 1, 0, 's'}, - {"logdir", 1, 0, 'l'}, - {"baselog", 1, 0, 'b'}, - {"gnuplot", 1, 0, 'G'}, - {"duration", 1, 0, 'D'}, - {"ftrace", 0, 0, 'T'}, - {"pi_enabled", 0, 0, 'T'}, - {"die_on_dmiss", 0, 0, 'M'}, -#ifdef AQUOSA - {"qos", 0, 0, 'q'}, - {"frag",1, 0, 'g'}, -#endif - {0, 0, 0, 0} - }; - -#ifdef AQUOSA - while (( ch = getopt_long(argc,argv,"D:GKhfrb:s:l:qg:t:TM", - long_options, &longopt_idx)) != -1) -#else - while (( ch = getopt_long(argc,argv,"D:GKhfrb:s:l:t:TM", - long_options, &longopt_idx)) != -1) -#endif - { - switch (ch) - { - case 'h': - usage(NULL, EXIT_SUCCESS); - break; - case 'f': - if (opts->policy != other) - usage("Cannot set multiple policies", - EXIT_INV_COMMANDLINE); - opts->policy = fifo; - break; - case 'r': - if (opts->policy != other) - usage("Cannot set multiple policies", - EXIT_INV_COMMANDLINE); - opts->policy = rr; - break; - case 'b': - if (!opts->logdir) - opts->logdir = strdup("."); - opts->logbasename = strdup(optarg); - break; - case 's': - opts->spacing = strtol(optarg, NULL, 0); - if (opts->spacing < 0) - usage("Cannot set negative spacing", - EXIT_INV_COMMANDLINE); - break; - case 'l': - opts->logdir = strdup(optarg); - lstat(opts->logdir, &dirstat); - if (! S_ISDIR(dirstat.st_mode)) - usage("Cannot stat log directory", - EXIT_INV_COMMANDLINE); - break; - case 't': - if (opts->nthreads > 0) - { - opts->threads_data = realloc( - opts->threads_data, - (opts->nthreads+1) * \ - sizeof(thread_data_t)); - opts->threads_data[opts->nthreads+1].phases_data = - malloc(sizeof(phase_data_t)); - } - parse_thread_args(optarg, opts->nthreads, - &opts->threads_data[opts->nthreads], - opts->policy); - opts->nthreads++; - break; - case 'G': - opts->gnuplot = 1; - break; - case 'D': - opts->duration = strtol(optarg, NULL, 10); - if (opts->duration < 0) - usage("Cannot set negative duration", - EXIT_INV_COMMANDLINE); - break; - case 'K': - opts->lock_pages = 0; - break; - case 'T': - opts->ftrace = 1; - break; - case 'P': - opts->pi_enabled = 1; - break; - case 'M': - opts->die_on_dmiss = 1; - break; -#ifdef AQUOSA - case 'q': - if (opts->policy != other) - usage("Cannot set multiple policies", - EXIT_INV_COMMANDLINE); - opts->policy = aquosa; - break; - case 'g': - opts->fragment = strtol(optarg, NULL, 10); - if (opts->fragment < 1 || opts->fragment > 16) - usage("Fragment divisor must be between" - "1 and 16", EXIT_INV_COMMANDLINE); - break; -#endif - default: - log_error("Invalid option %c", ch); - usage(NULL, EXIT_INV_COMMANDLINE); - } - } - - if ( opts->nthreads < 1) - usage("You have to set parameters for at least one thread", - EXIT_INV_COMMANDLINE); - -} - void parse_command_line(int argc, char **argv, rtapp_options_t *opts) { -#ifdef JSON struct stat config_file_stat;
if (argc < 2) @@ -369,10 +46,4 @@ parse_command_line(int argc, char **argv, rtapp_options_t *opts) parse_config_stdin(opts); return; } -#endif - - parse_command_line_options(argc, argv, opts); - opts->resources = NULL; - opts->nresources = 0; } - diff --git a/src/rt-app_args.h b/src/rt-app_args.h index b7135c3..2f66a22 100644 --- a/src/rt-app_args.h +++ b/src/rt-app_args.h @@ -47,9 +47,6 @@ void usage (const char* msg, int ex_code);
void -parse_thread_args(char *arg, int idx, thread_data_t *tdata, policy_t def_policy); - -void parse_command_line(int argc, char **argv, rtapp_options_t *opts);
#endif // _RTAPP_ARGS_H_