diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2011-01-13 12:05:08 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-01-30 12:06:07 -0500 |
commit | c013cd8625b0ebb28f71337109d3fbfdf0a6b621 (patch) | |
tree | 2215d2d16ddb415f3f7b0564ea67e34f1b79e2a2 | |
parent | 53d9a93a623d0edc662b6d00b3dea247a3f9224b (diff) |
Modify RTSpin so that it can read execution time data from a CSV file.
Still need to figure out what to do with the period is less than the
exec_cost (or budget).
-rw-r--r-- | bin/rtspin.c | 152 |
1 files changed, 137 insertions, 15 deletions
diff --git a/bin/rtspin.c b/bin/rtspin.c index 649da45..3e22ffe 100644 --- a/bin/rtspin.c +++ b/bin/rtspin.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <unistd.h> | 5 | #include <unistd.h> |
6 | #include <time.h> | 6 | #include <time.h> |
7 | #include <assert.h> | ||
7 | 8 | ||
8 | 9 | ||
9 | #include "litmus.h" | 10 | #include "litmus.h" |
@@ -27,12 +28,86 @@ static double wctime() | |||
27 | return (tv.tv_sec + 1E-6 * tv.tv_usec); | 28 | return (tv.tv_sec + 1E-6 * tv.tv_usec); |
28 | } | 29 | } |
29 | 30 | ||
30 | void usage(char *error) { | 31 | static void usage(char *error) { |
31 | fprintf(stderr, "Error: %s\n", error); | 32 | fprintf(stderr, "Error: %s\n", error); |
32 | fprintf(stderr, | 33 | fprintf(stderr, |
33 | "Usage: rt_spin [-w] [-p PARTITION] [-c CLASS] WCET PERIOD DURATION\n" | 34 | "Usage:\n" |
34 | " rt_spin -l\n"); | 35 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" |
35 | exit(1); | 36 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" |
37 | " rt_spin -l\n" | ||
38 | "\n" | ||
39 | "COMMON-OPTS = [-w] [-p PARTITION] [-c CLASS] [-s SCALE]\n" | ||
40 | "\n" | ||
41 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n"); | ||
42 | exit(EXIT_FAILURE); | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * returns the character that made processing stop, newline or EOF | ||
47 | */ | ||
48 | static int skip_to_next_line(FILE *fstream) | ||
49 | { | ||
50 | int ch; | ||
51 | for (ch = fgetc(fstream); ch != EOF && ch != '\n'; ch = fgetc(fstream)); | ||
52 | return ch; | ||
53 | } | ||
54 | |||
55 | static void skip_comments(FILE *fstream) | ||
56 | { | ||
57 | int ch; | ||
58 | for (ch = fgetc(fstream); ch == '#'; ch = fgetc(fstream)) | ||
59 | skip_to_next_line(fstream); | ||
60 | ungetc(ch, fstream); | ||
61 | } | ||
62 | |||
63 | static void get_exec_times(const char *file, const int column, | ||
64 | int *num_jobs, double **exec_times) | ||
65 | { | ||
66 | FILE *fstream; | ||
67 | int cur_job, cur_col, ch; | ||
68 | *num_jobs = 0; | ||
69 | |||
70 | fstream = fopen(file, "r"); | ||
71 | if (!fstream) | ||
72 | bail_out("could not open execution time file"); | ||
73 | |||
74 | /* figure out the number of jobs */ | ||
75 | do { | ||
76 | skip_comments(fstream); | ||
77 | ch = skip_to_next_line(fstream); | ||
78 | if (ch != EOF) | ||
79 | ++(*num_jobs); | ||
80 | } while (ch != EOF); | ||
81 | |||
82 | if (-1 == fseek(fstream, 0L, SEEK_SET)) | ||
83 | bail_out("rewinding file failed"); | ||
84 | |||
85 | /* allocate space for exec times */ | ||
86 | *exec_times = calloc(*num_jobs, sizeof(*exec_times)); | ||
87 | if (!*exec_times) | ||
88 | bail_out("couldn't allocate memory"); | ||
89 | |||
90 | for (cur_job = 0; cur_job < *num_jobs && !feof(fstream); ++cur_job) { | ||
91 | |||
92 | skip_comments(fstream); | ||
93 | |||
94 | for (cur_col = 1; cur_col < column; ++cur_col) { | ||
95 | /* discard input until we get to the column we want */ | ||
96 | fscanf(fstream, "%*s,"); | ||
97 | } | ||
98 | |||
99 | /* get the desired exec. time */ | ||
100 | if (1 != fscanf(fstream, "%lf", (*exec_times)+cur_job)) { | ||
101 | fprintf(stderr, "invalid execution time near line %d\n", | ||
102 | cur_job); | ||
103 | exit(EXIT_FAILURE); | ||
104 | } | ||
105 | |||
106 | skip_to_next_line(fstream); | ||
107 | } | ||
108 | |||
109 | assert(cur_job == *num_jobs); | ||
110 | fclose(fstream); | ||
36 | } | 111 | } |
37 | 112 | ||
38 | #define NUMS 4096 | 113 | #define NUMS 4096 |
@@ -144,7 +219,7 @@ static int job(double exec_time, double program_end) | |||
144 | } | 219 | } |
145 | } | 220 | } |
146 | 221 | ||
147 | #define OPTSTR "p:c:wld:ve" | 222 | #define OPTSTR "p:c:wld:veo:f:s:" |
148 | 223 | ||
149 | int main(int argc, char** argv) | 224 | int main(int argc, char** argv) |
150 | { | 225 | { |
@@ -159,9 +234,14 @@ int main(int argc, char** argv) | |||
159 | int test_loop = 0; | 234 | int test_loop = 0; |
160 | int skip_config = 0; | 235 | int skip_config = 0; |
161 | int verbose = 0; | 236 | int verbose = 0; |
237 | int column = 1; | ||
238 | const char *file = NULL; | ||
162 | int want_enforcement = 0; | 239 | int want_enforcement = 0; |
163 | double duration, start; | 240 | double duration = 0, start; |
241 | double *exec_times = NULL; | ||
242 | double scale = 1.0; | ||
164 | task_class_t class = RT_CLASS_HARD; | 243 | task_class_t class = RT_CLASS_HARD; |
244 | int cur_job, num_jobs; | ||
165 | 245 | ||
166 | progname = argv[0]; | 246 | progname = argv[0]; |
167 | 247 | ||
@@ -194,6 +274,15 @@ int main(int argc, char** argv) | |||
194 | case 'v': | 274 | case 'v': |
195 | verbose = 1; | 275 | verbose = 1; |
196 | break; | 276 | break; |
277 | case 'o': | ||
278 | column = atoi(optarg); | ||
279 | break; | ||
280 | case 'f': | ||
281 | file = optarg; | ||
282 | break; | ||
283 | case 's': | ||
284 | scale = atof(optarg); | ||
285 | break; | ||
197 | case ':': | 286 | case ':': |
198 | usage("Argument missing."); | 287 | usage("Argument missing."); |
199 | break; | 288 | break; |
@@ -213,23 +302,45 @@ int main(int argc, char** argv) | |||
213 | return 0; | 302 | return 0; |
214 | } | 303 | } |
215 | 304 | ||
216 | if (argc - optind < 3) | 305 | if (file) { |
217 | usage("Arguments missing."); | 306 | get_exec_times(file, column, &num_jobs, &exec_times); |
307 | |||
308 | if (argc - optind < 2) | ||
309 | usage("Arguments missing."); | ||
310 | |||
311 | for (cur_job = 0; cur_job < num_jobs; ++cur_job) { | ||
312 | /* convert the execution time to seconds */ | ||
313 | duration += exec_times[cur_job] * 0.001; | ||
314 | } | ||
315 | } else { | ||
316 | /* | ||
317 | * if we're not reading from the CSV file, then we need | ||
318 | * three parameters | ||
319 | */ | ||
320 | if (argc - optind < 3) | ||
321 | usage("Arguments missing."); | ||
322 | } | ||
323 | |||
218 | wcet_ms = atof(argv[optind + 0]); | 324 | wcet_ms = atof(argv[optind + 0]); |
219 | period_ms = atof(argv[optind + 1]); | 325 | period_ms = atof(argv[optind + 1]); |
220 | duration = atof(argv[optind + 2]); | 326 | |
221 | wcet = wcet_ms * __NS_PER_MS; | 327 | wcet = wcet_ms * __NS_PER_MS; |
222 | period = period_ms * __NS_PER_MS; | 328 | period = period_ms * __NS_PER_MS; |
223 | if (wcet <= 0) | 329 | if (wcet <= 0) |
224 | usage("The worst-case execution time must be a " | 330 | usage("The worst-case execution time must be a " |
225 | "positive number."); | 331 | "positive number."); |
226 | if (period <= 0) | 332 | if (period <= 0) |
227 | usage("The period must be a positive number."); | 333 | usage("The period must be a positive number."); |
228 | if (wcet > period) { | 334 | if (!file && wcet > period) { |
229 | usage("The worst-case execution time must not " | 335 | usage("The worst-case execution time must not " |
230 | "exceed the period."); | 336 | "exceed the period."); |
231 | } | 337 | } |
232 | 338 | ||
339 | if (!file) | ||
340 | duration = atof(argv[optind + 2]); | ||
341 | else if (file && num_jobs > 1) | ||
342 | duration += period_ms * 0.001 * (num_jobs - 1); | ||
343 | |||
233 | if (migrate) { | 344 | if (migrate) { |
234 | ret = be_migrate_to(cpu); | 345 | ret = be_migrate_to(cpu); |
235 | if (ret < 0) | 346 | if (ret < 0) |
@@ -240,7 +351,6 @@ int main(int argc, char** argv) | |||
240 | want_enforcement ? PRECISE_ENFORCEMENT | 351 | want_enforcement ? PRECISE_ENFORCEMENT |
241 | : NO_ENFORCEMENT, | 352 | : NO_ENFORCEMENT, |
242 | migrate); | 353 | migrate); |
243 | |||
244 | if (ret < 0) | 354 | if (ret < 0) |
245 | bail_out("could not setup rt task params"); | 355 | bail_out("could not setup rt task params"); |
246 | 356 | ||
@@ -261,12 +371,24 @@ int main(int argc, char** argv) | |||
261 | 371 | ||
262 | start = wctime(); | 372 | start = wctime(); |
263 | 373 | ||
264 | /* 90% wcet, in seconds */ | 374 | if (file) { |
265 | while (job(wcet_ms * 0.0009, start + duration)); | 375 | /* use times read from the CSV file */ |
376 | for (cur_job = 0; cur_job < num_jobs; ++cur_job) { | ||
377 | /* convert job's length to seconds */ | ||
378 | job(exec_times[cur_job] * 0.001 * scale, | ||
379 | start + duration); | ||
380 | } | ||
381 | } else { | ||
382 | /* conver to seconds and scale */ | ||
383 | while (job(wcet_ms * 0.001 * scale, start + duration)); | ||
384 | } | ||
266 | 385 | ||
267 | ret = task_mode(BACKGROUND_TASK); | 386 | ret = task_mode(BACKGROUND_TASK); |
268 | if (ret != 0) | 387 | if (ret != 0) |
269 | bail_out("could not become regular task (huh?)"); | 388 | bail_out("could not become regular task (huh?)"); |
270 | 389 | ||
390 | if (file) | ||
391 | free(exec_times); | ||
392 | |||
271 | return 0; | 393 | return 0; |
272 | } | 394 | } |