aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2011-01-13 12:05:08 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-01-30 12:06:07 -0500
commitc013cd8625b0ebb28f71337109d3fbfdf0a6b621 (patch)
tree2215d2d16ddb415f3f7b0564ea67e34f1b79e2a2
parent53d9a93a623d0edc662b6d00b3dea247a3f9224b (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.c152
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
30void usage(char *error) { 31static 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 */
48static 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
55static 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
63static 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
149int main(int argc, char** argv) 224int 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}