From 046f99f037d0c862e7bab8856169aa742c8ad65f Mon Sep 17 00:00:00 2001 From: Andrea Bastoni Date: Tue, 15 Jun 2010 16:35:17 -0400 Subject: [EDF-fm] Add rt_launch_edffm and support for edffm task creation --- SConstruct | 1 + bin/rt_launch_edffm.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ bin/rtspin_edffm.c | 2 +- include/litmus.h | 3 ++ src/task.c | 29 +++++++++++ 5 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 bin/rt_launch_edffm.c diff --git a/SConstruct b/SConstruct index 7ae2883..c0a5f6e 100644 --- a/SConstruct +++ b/SConstruct @@ -209,6 +209,7 @@ mtrt.Program('base_mt_task', 'bin/base_mt_task.c') rt.Program('rt_launch', ['bin/rt_launch.c', 'bin/common.c']) rt.Program('rtspin', ['bin/rtspin.c', 'bin/common.c']) rt.Program('rtspin_edffm', ['bin/rtspin_edffm.c', 'bin/common.c']) +rt.Program('rt_launch_edffm', ['bin/rt_launch_edffm.c', 'bin/common.c']) rt.Program('release_ts', 'bin/release_ts.c') rtm.Program('measure_syscall', 'bin/null_call.c') diff --git a/bin/rt_launch_edffm.c b/bin/rt_launch_edffm.c new file mode 100644 index 0000000..fcb895e --- /dev/null +++ b/bin/rt_launch_edffm.c @@ -0,0 +1,133 @@ +#include +#include +#include +#include +#include +#include + +#include "litmus.h" +#include "common.h" + +typedef struct { + int wait; + char * exec_path; + char ** argv; +} startup_info_t; + + +int launch(void *task_info_p) { + startup_info_t *info = (startup_info_t*) task_info_p; + int ret; + if (info->wait) { + ret = wait_for_ts_release(); + if (ret != 0) + perror("wait_for_ts_release()"); + } + ret = execvp(info->exec_path, info->argv); + perror("execv failed"); + return ret; +} + +void usage(char *error) { + fprintf(stderr, "%s\nUsage: rt_launch [-w][-v][-p cpu][-c hrt | srt | be] wcet period" + " fracnum1 fracden2 fracnum2 fracden2 cpu1 cpu2 program [arg1 arg2 ...]\n" + "\t-w\tSynchronous release\n" + "\t-v\tVerbose\n" + "\t-p\tcpu (or initial cpu)\n" + "\t-c\tClass\n" + "\twcet, period in ms\n" + "\tprogram to be launched\n", + error); + exit(1); +} + + +#define OPTSTR "p:c:vw" + +int main(int argc, char** argv) +{ + int ret; + lt_t wcet; + lt_t period; + /* [num,den] */ + lt_t frac1[2], frac2[2]; + int cpu1, cpu2; + int migrate = 0; + int cpu = 0; + int opt; + int verbose = 0; + int wait = 0; + startup_info_t info; + task_class_t class = RT_CLASS_HARD; + + while ((opt = getopt(argc, argv, OPTSTR)) != -1) { + switch (opt) { + case 'w': + wait = 1; + break; + case 'v': + verbose = 1; + break; + case 'p': + cpu = atoi(optarg); + migrate = 1; + break; + case 'c': + class = str2class(optarg); + if (class == -1) + usage("Unknown task class."); + break; + + case ':': + usage("Argument missing."); + break; + case '?': + default: + usage("Bad argument."); + break; + } + } + + signal(SIGUSR1, SIG_IGN); + + if (argc - optind < 8) + usage("Arguments missing."); + wcet = ms2lt(atoi(argv[optind + 0])); + period = ms2lt(atoi(argv[optind + 1])); + /* frac num, den = 0 means fixed task */ + frac1[0] = atoi(argv[optind + 2]); + frac1[1] = atoi(argv[optind + 3]); + frac2[0] = atoi(argv[optind + 4]); + frac2[1] = atoi(argv[optind + 5]); + cpu1 = atoi(argv[optind + 6]); + cpu2 = atoi(argv[optind + 7]); + if (wcet <= 0) + usage("The worst-case execution time must be a " + "positive number."); + if (period <= 0) + usage("The period must be a positive number."); + if (wcet > period) { + usage("The worst-case execution time must not " + "exceed the period."); + } + info.exec_path = argv[optind + 8]; + info.argv = argv + optind + 8; + info.wait = wait; + if (migrate) { + ret = be_migrate_to(cpu); + if (ret < 0) + bail_out("could not migrate to target partition"); + } + /* create in src/task.c a new wrapper for the __launch_rt_task + * which takes the fraction and the cpus */ + ret = __create_rt_task_edffm(launch, &info, cpu, wcet, period, frac1, + frac2, cpu1, cpu2, class); + + + if (ret < 0) + bail_out("could not create rt child process"); + else if (verbose) + printf("%d\n", ret); + + return 0; +} diff --git a/bin/rtspin_edffm.c b/bin/rtspin_edffm.c index 04dce0a..d28d028 100644 --- a/bin/rtspin_edffm.c +++ b/bin/rtspin_edffm.c @@ -201,7 +201,7 @@ int main(int argc, char** argv) return 0; } - if (argc - optind < 3) + if (argc - optind < 9) usage("Arguments missing."); wcet_ms = atof(argv[optind + 0]); period_ms = atof(argv[optind + 1]); diff --git a/include/litmus.h b/include/litmus.h index e27b10d..3aa790f 100644 --- a/include/litmus.h +++ b/include/litmus.h @@ -90,6 +90,9 @@ typedef int (*rt_fn_t)(void*); int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period); int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, task_class_t cls); +int __create_rt_task_edffm(rt_fn_t rt_prog, void *arg, int cpu, int wcet, + int period, lt_t *frac1, lt_t *frac2, + int cpu1, int cpu2, task_class_t class); /* per-task modes */ enum rt_task_mode_t { diff --git a/src/task.c b/src/task.c index 4d237bd..905ab9c 100644 --- a/src/task.c +++ b/src/task.c @@ -40,6 +40,35 @@ int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, rt_setup_fn_t setup, return rt_task; } +int __create_rt_task_edffm(rt_fn_t rt_prog, void *arg, int cpu, int wcet, + int period, lt_t *frac1, lt_t *frac2, + int cpu1, int cpu2, task_class_t class) +{ + struct rt_task params; + params.cpu = cpu; + params.period = period; + params.exec_cost = wcet; + params.cls = class; + params.phase = 0; + /* enforce budget for tasks that might not use sleep_next_period() */ + params.budget_policy = QUANTUM_ENFORCEMENT; + + /* edf-fm check on denominators for migratory tasks */ + if (frac1[1] != 0 && frac2[1] != 0) { + /* edf-fm migrat task */ + params.nr_cpus = 1; + params.cpus[0] = cpu1; + params.cpus[1] = cpu2; + params.fraction[0][0] = frac1[0]; + params.fraction[1][0] = frac1[1]; + params.fraction[0][1] = frac2[0]; + params.fraction[1][1] = frac2[1]; + } + + return __launch_rt_task(rt_prog, arg, + (rt_setup_fn_t) set_rt_task_param, ¶ms); +} + int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, task_class_t class) { -- cgit v1.2.2