diff options
| author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2014-05-09 05:11:35 -0400 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2014-06-03 02:38:40 -0400 |
| commit | 4cc5780a04d827e075a383b2c37a7fca304c3607 (patch) | |
| tree | 65cd2b416e14fa85e85c8dac6ab024b4f84e9f2a | |
| parent | a5df594496740ef2284fdaab8430af84e835ad57 (diff) | |
Modernize rt_launch; remove internal API cruft
Switch rt_launch to use a more modern way to launch real-time tasks.
This makes rt_launch more flexible, makes it more similar to rtspin,
and also allows to let us get rid of a chunk of old, inflexible code
in liblitmus that wasn't really serving any useful purpose anymore.
| -rw-r--r-- | bin/rt_launch.c | 172 | ||||
| -rw-r--r-- | include/internal.h | 5 | ||||
| -rw-r--r-- | include/litmus.h | 29 | ||||
| -rw-r--r-- | src/task.c | 58 |
4 files changed, 112 insertions, 152 deletions
diff --git a/bin/rt_launch.c b/bin/rt_launch.c index 5e29893..c468b68 100644 --- a/bin/rt_launch.c +++ b/bin/rt_launch.c | |||
| @@ -8,64 +8,63 @@ | |||
| 8 | #include "litmus.h" | 8 | #include "litmus.h" |
| 9 | #include "common.h" | 9 | #include "common.h" |
| 10 | 10 | ||
| 11 | typedef struct { | 11 | const char *usage_msg = |
| 12 | int wait; | 12 | "Usage: rt_launch OPTIONS wcet period program [arg1 arg2 ...]\n" |
| 13 | char * exec_path; | 13 | " -w wait for synchronous release\n" |
| 14 | char ** argv; | 14 | " -v verbose (prints PID)\n" |
| 15 | } startup_info_t; | 15 | " -p CPU physical partition or cluster to assign to\n" |
| 16 | 16 | " -r VCPU virtual CPU to attach to (irrelevant to most plugins)\n" | |
| 17 | 17 | " -d DEADLINE relative deadline, implicit by default (in ms)\n" | |
| 18 | int launch(void *task_info_p) { | 18 | " -o OFFSET offset (also known as phase), zero by default (in ms)\n" |
| 19 | startup_info_t *info = (startup_info_t*) task_info_p; | 19 | " -q PRIORITY priority to use (ignored by EDF plugins, highest=1, lowest=511)\n" |
| 20 | int ret; | 20 | " -c be|srt|hrt task class (best-effort, soft real-time, hard real-time)\n" |
| 21 | if (info->wait) { | 21 | " -e turn off budget enforcement (DANGEROUS: can result in lockup)\n" |
| 22 | ret = wait_for_ts_release(); | 22 | " wcet, period reservation parameters (in ms)\n" |
| 23 | if (ret != 0) | 23 | " program path to the binary to be launched\n" |
| 24 | perror("wait_for_ts_release()"); | 24 | "\n"; |
| 25 | } | ||
| 26 | ret = execvp(info->exec_path, info->argv); | ||
| 27 | perror("execv failed"); | ||
| 28 | return ret; | ||
| 29 | } | ||
| 30 | 25 | ||
| 31 | void usage(char *error) { | 26 | void usage(char *error) { |
| 32 | fprintf(stderr, "%s\nUsage: rt_launch [-w][-v][-p partition/cluster [-z cluster size]][-q prio][-c hrt | srt | be] wcet period program [arg1 arg2 ...]\n" | 27 | fprintf(stderr, "%s\n%s", error, usage_msg); |
| 33 | "\t-w\tSynchronous release\n" | ||
| 34 | "\t-v\tVerbose\n" | ||
| 35 | "\t-p\tpartition or cluster\n" | ||
| 36 | "\t-z\tsize of cluster (default = 1 for partitioned)\n" | ||
| 37 | "\t-c\tClass\n" | ||
| 38 | "\twcet, period in ms\n" | ||
| 39 | "\tprogram to be launched\n", | ||
| 40 | error); | ||
| 41 | exit(1); | 28 | exit(1); |
| 42 | } | 29 | } |
| 43 | 30 | ||
| 31 | #define OPTSTR "wp:q:c:er:b:o:d:vh" | ||
| 44 | 32 | ||
| 45 | #define OPTSTR "p:c:vwq:" | 33 | int main(int argc, char** argv) |
| 46 | |||
| 47 | int main(int argc, char** argv) | ||
| 48 | { | 34 | { |
| 49 | int ret; | 35 | int ret, opt; |
| 50 | lt_t wcet; | 36 | lt_t wcet; |
| 51 | lt_t period; | 37 | lt_t period; |
| 52 | int migrate = 0; | 38 | lt_t offset; |
| 53 | int cluster = 0; | 39 | lt_t deadline; |
| 54 | int opt; | 40 | double wcet_ms, period_ms, offset_ms, deadline_ms; |
| 55 | int verbose = 0; | 41 | unsigned int priority; |
| 56 | int wait = 0; | 42 | int migrate; |
| 57 | startup_info_t info; | 43 | int cluster; |
| 58 | task_class_t class = RT_CLASS_HARD; | 44 | int reservation; |
| 59 | unsigned int priority = LITMUS_LOWEST_PRIORITY; | 45 | int wait; |
| 46 | int want_enforcement; | ||
| 47 | int verbose; | ||
| 48 | task_class_t class; | ||
| 49 | struct rt_task param; | ||
| 50 | |||
| 51 | /* Reasonable defaults */ | ||
| 52 | verbose = 0; | ||
| 53 | offset_ms = 0; | ||
| 54 | deadline_ms = 0; | ||
| 55 | priority = LITMUS_LOWEST_PRIORITY; | ||
| 56 | want_enforcement = 1; /* safety: default to enforcement */ | ||
| 57 | wait = 0; /* don't wait for task system release */ | ||
| 58 | class = RT_CLASS_SOFT; /* ignored by most plugins */ | ||
| 59 | migrate = 0; /* assume global unless -p is specified */ | ||
| 60 | cluster = -1; /* where to migrate to, invalid by default */ | ||
| 61 | reservation = -1; /* set if task should attach to virtual CPU */ | ||
| 60 | 62 | ||
| 61 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | 63 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { |
| 62 | switch (opt) { | 64 | switch (opt) { |
| 63 | case 'w': | 65 | case 'w': |
| 64 | wait = 1; | 66 | wait = 1; |
| 65 | break; | 67 | break; |
| 66 | case 'v': | ||
| 67 | verbose = 1; | ||
| 68 | break; | ||
| 69 | case 'p': | 68 | case 'p': |
| 70 | cluster = atoi(optarg); | 69 | cluster = atoi(optarg); |
| 71 | migrate = 1; | 70 | migrate = 1; |
| @@ -80,7 +79,28 @@ int main(int argc, char** argv) | |||
| 80 | if (class == -1) | 79 | if (class == -1) |
| 81 | usage("Unknown task class."); | 80 | usage("Unknown task class."); |
| 82 | break; | 81 | break; |
| 83 | 82 | case 'e': | |
| 83 | want_enforcement = 0; | ||
| 84 | break; | ||
| 85 | case 'r': | ||
| 86 | reservation = atoi(optarg); | ||
| 87 | break; | ||
| 88 | case 'o': | ||
| 89 | offset_ms = atof(optarg); | ||
| 90 | break; | ||
| 91 | case 'd': | ||
| 92 | deadline_ms = atof(optarg); | ||
| 93 | if (!deadline_ms || deadline_ms < 0) { | ||
| 94 | usage("The relative deadline must be a positive" | ||
| 95 | " number."); | ||
| 96 | } | ||
| 97 | break; | ||
| 98 | case 'v': | ||
| 99 | verbose = 1; | ||
| 100 | break; | ||
| 101 | case 'h': | ||
| 102 | usage(""); | ||
| 103 | break; | ||
| 84 | case ':': | 104 | case ':': |
| 85 | usage("Argument missing."); | 105 | usage("Argument missing."); |
| 86 | break; | 106 | break; |
| @@ -95,33 +115,65 @@ int main(int argc, char** argv) | |||
| 95 | 115 | ||
| 96 | if (argc - optind < 3) | 116 | if (argc - optind < 3) |
| 97 | usage("Arguments missing."); | 117 | usage("Arguments missing."); |
| 98 | wcet = ms2ns(atoi(argv[optind + 0])); | 118 | |
| 99 | period = ms2ns(atoi(argv[optind + 1])); | 119 | wcet_ms = atof(argv[optind + 0]); |
| 120 | period_ms = atof(argv[optind + 1]); | ||
| 121 | |||
| 122 | wcet = ms2ns(wcet_ms); | ||
| 123 | period = ms2ns(period_ms); | ||
| 124 | offset = ms2ns(offset_ms); | ||
| 125 | deadline = ms2ns(deadline_ms); | ||
| 100 | if (wcet <= 0) | 126 | if (wcet <= 0) |
| 101 | usage("The worst-case execution time must be a " | 127 | usage("The worst-case execution time must be a " |
| 102 | "positive number."); | 128 | "positive number."); |
| 103 | if (period <= 0) | 129 | if (period <= 0) |
| 104 | usage("The period must be a positive number."); | 130 | usage("The period must be a positive number."); |
| 105 | if (wcet > period) { | 131 | if (wcet > period) { |
| 106 | usage("The worst-case execution time must not " | 132 | usage("The worst-case execution time must not " |
| 107 | "exceed the period."); | 133 | "exceed the period."); |
| 108 | } | 134 | } |
| 109 | info.exec_path = argv[optind + 2]; | 135 | |
| 110 | info.argv = argv + optind + 2; | ||
| 111 | info.wait = wait; | ||
| 112 | if (migrate) { | 136 | if (migrate) { |
| 113 | ret = be_migrate_to_domain(cluster); | 137 | ret = be_migrate_to_domain(cluster); |
| 114 | if (ret < 0) | 138 | if (ret < 0) |
| 115 | bail_out("could not migrate to target partition or cluster"); | 139 | bail_out("could not migrate to target partition or cluster."); |
| 116 | } | 140 | } |
| 117 | ret = __create_rt_task(launch, &info, cluster, wcet, period, | ||
| 118 | priority, class); | ||
| 119 | |||
| 120 | 141 | ||
| 142 | init_rt_task_param(¶m); | ||
| 143 | param.exec_cost = wcet; | ||
| 144 | param.period = period; | ||
| 145 | param.phase = offset; | ||
| 146 | param.relative_deadline = deadline; | ||
| 147 | param.priority = priority; | ||
| 148 | param.cls = class; | ||
| 149 | param.budget_policy = (want_enforcement) ? | ||
| 150 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
| 151 | if (migrate) { | ||
| 152 | if (reservation >= 0) | ||
| 153 | param.cpu = reservation; | ||
| 154 | else | ||
| 155 | param.cpu = domain_to_first_cpu(cluster); | ||
| 156 | } | ||
| 157 | ret = set_rt_task_param(gettid(), ¶m); | ||
| 121 | if (ret < 0) | 158 | if (ret < 0) |
| 122 | bail_out("could not create rt child process"); | 159 | bail_out("could not setup rt task params"); |
| 123 | else if (verbose) | ||
| 124 | printf("%d\n", ret); | ||
| 125 | 160 | ||
| 126 | return 0; | 161 | init_litmus(); |
| 162 | |||
| 163 | ret = task_mode(LITMUS_RT_TASK); | ||
| 164 | if (ret != 0) | ||
| 165 | bail_out("could not become RT task"); | ||
| 166 | |||
