aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2010-11-29 11:44:11 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2010-11-29 11:44:11 -0500
commit9a68dbea3ce813ead95b3b4b3ceb2542bc5ca670 (patch)
treea9a25a9bfa27cf6899fb651b8c78e20b4c37f5aa
parente83917699a930e63a34a8b112258b1d5e4031048 (diff)
Feature: Allow rtspin to change its execution time dynamically
New controls added to rtspin that allow the user to specify different execution time behaviors for rtspin. Behaviors are characterized by waveforms. For example, execution time may follow a sine-wave pattern over time. Supported waveforms are: flat, sin, triangle, box, sawtooth, and reverse sawtooth.
-rw-r--r--SConstruct2
-rw-r--r--bin/rtspin.c220
2 files changed, 214 insertions, 8 deletions
diff --git a/SConstruct b/SConstruct
index c41e41e..94d5194 100644
--- a/SConstruct
+++ b/SConstruct
@@ -177,7 +177,7 @@ if not (env.GetOption('clean') or env.GetOption('help')):
177 177
178# link with liblitmus 178# link with liblitmus
179rt = env.Clone( 179rt = env.Clone(
180 LIBS = Split('litmus rt'), 180 LIBS = Split('litmus rt m'),
181 LIBPATH = '.' 181 LIBPATH = '.'
182) 182)
183rt.Append(LINKFLAGS = '-static') 183rt.Append(LINKFLAGS = '-static')
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 650fcb3..939d507 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -4,7 +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 7#include <math.h>
8 8
9#include "litmus.h" 9#include "litmus.h"
10#include "common.h" 10#include "common.h"
@@ -30,8 +30,14 @@ static double wctime()
30void usage(char *error) { 30void usage(char *error) {
31 fprintf(stderr, "Error: %s\n", error); 31 fprintf(stderr, "Error: %s\n", error);
32 fprintf(stderr, 32 fprintf(stderr,
33 "Usage: rt_spin [-w] [-p PARTITION] [-c CLASS] WCET PERIOD DURATION\n" 33 "Usage: rt_spin [-w] [-p PARTITION] [-c CLASS] [-A fp# -B fp# -W wave# -M max_wcet -P #jobs [-D #jobs]] WCET PERIOD DURATION\n"
34 " rt_spin -l\n"); 34 " rt_spin -l\n"
35 " -A: Feedback control 'A' parameter\n"
36 " -B: Feedback control 'B' parameter\n"
37 " -W: 0 = flat; 1 = sine; 2 = triangle; 3 = box; 4 = sawtooth; 5 = reverse sawtooth\n"
38 " -M: max wcet (WCET is assumed min wcet)\n"
39 " -P: period of execution behavior wave\n"
40 " -D: Number of jobs wave should hold at extrema points (default = 0)\n");
35 exit(1); 41 exit(1);
36} 42}
37 43
@@ -133,7 +139,107 @@ static int job(double exec_time)
133 return 0; 139 return 0;
134} 140}
135 141
136#define OPTSTR "p:c:wld:ve" 142fp_t float_to_frac(double f)
143{
144 fpbuf_t num;
145 fpbuf_t denom = 1000; /* express in 1000ths */
146
147 num = (fpbuf_t)f * denom;
148 if(f != floor(f))
149 {
150 num += (fpbuf_t)(f - floor(f)) * denom;
151 }
152
153 return(_frac(num, denom));
154}
155
156#define OPTSTR "p:c:wld:veA:B:W:M:P:D:"
157
158struct wave_data;
159typedef double(*wave_func)(int, struct wave_data*);
160
161struct wave_data
162{
163 double min_wcet_ms;
164 double max_wcet_ms;
165 double amplitude;
166 int period;
167 int extrema_delay;
168 int min_point;
169 int max_point;
170 wave_func f;
171};
172
173double flat_wave(int count, struct wave_data* w)
174{
175 return(w->min_wcet_ms);
176}
177
178double sin_wave(int count, struct wave_data* w)
179{
180 double step = count % w->period;
181 double exe = w->min_wcet_ms + w->amplitude * sin(M_PI*step/w->period);
182 return(exe);
183}
184
185double tri_wave(int count, struct wave_data* w)
186{
187 double step = count % w->period;
188 double v = 2.0 * (step/w->period - floor(step/w->period + 0.5));
189 double exe = w->min_wcet_ms + w->amplitude * abs(v);
190 return(exe);
191}
192
193double box_wave(int count, struct wave_data* w)
194{
195 double step = count % w->period;
196 double exe = w->min_wcet_ms + w->amplitude *((step/w->period < 0.5) ? 0 : 1);
197 return(exe);
198}
199
200double saw_wave(int count, struct wave_data* w)
201{
202 double step = (count % w->period)/2.0;
203 double v = 2.0 * (step/w->period - floor(step/w->period + 0.5));
204 double exe;
205 if(v < 0) v += 1.0;
206 exe = w->min_wcet_ms + w->amplitude * v;
207 return(exe);
208}
209
210double rsaw_wave(int count, struct wave_data* w)
211{
212 double step = (count % w->period)/2.0;
213 double v = 2.0 * (step/w->period - floor(step/w->period + 0.5));
214 double exe;
215 if(v < 0) v += 1.0;
216 exe = w->max_wcet_ms - w->amplitude * v;
217 return(exe);
218}
219
220double get_execution_time(int count, struct wave_data* w)
221{
222 static int skips = 0;
223 static int delay_count = 0;
224
225 if(w->extrema_delay)
226 {
227 int at_max = (((count - skips) % w->period) == w->max_point);
228 int at_min = (((count - skips) % w->period) == w->min_point);
229
230 if((at_max || at_min) && delay_count++ < w->extrema_delay)
231 {
232 ++skips;
233 return((at_max) ? w->max_wcet_ms : w->min_wcet_ms);
234 }
235 else
236 {
237 delay_count = 0;
238 }
239 }
240
241 return(w->f(count - skips, w));
242}
137 243
138int main(int argc, char** argv) 244int main(int argc, char** argv)
139{ 245{
@@ -152,6 +258,18 @@ int main(int argc, char** argv)
152 double duration, start; 258 double duration, start;
153 task_class_t class = RT_CLASS_HARD; 259 task_class_t class = RT_CLASS_HARD;
154 260
261 fp_t A = LITMUS_FP_ZERO, B = LITMUS_FP_ZERO;
262 struct wave_data wave = {
263 .min_wcet_ms = 0.0,
264 .max_wcet_ms = 0.0,
265 .amplitude = 0.0,
266 .period = 0,
267 .extrema_delay = 0,
268 .max_point = 0,
269 .min_point = 0,
270 .f = NULL
271 };
272
155 progname = argv[0]; 273 progname = argv[0];
156 274
157 while ((opt = getopt(argc, argv, OPTSTR)) != -1) { 275 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
@@ -183,6 +301,49 @@ int main(int argc, char** argv)
183 case 'v': 301 case 'v':
184 verbose = 1; 302 verbose = 1;
185 break; 303 break;
304 case 'A':
305 A = float_to_frac(atof(optarg));
306 break;
307 case 'B':
308 B = float_to_frac(atof(optarg));
309 break;
310 case 'W':
311 switch(atoi(optarg))
312 {
313 case 0:
314 wave.f = flat_wave;
315 break;
316 case 1:
317 wave.f = sin_wave;
318 break;
319 case 2:
320 wave.f = tri_wave;
321 break;
322 case 3:
323 wave.f = box_wave;
324 break;
325 case 4:
326 wave.f = saw_wave;
327 break;
328 case 5:
329 wave.f = rsaw_wave;
330 break;
331 default:
332 usage("Bad wave identifier.");
333 break;
334 }
335 break;
336 case 'M':
337 wave.max_wcet_ms = atof(optarg);
338 break;
339 case 'P':
340 wave.period = atoi(optarg);
341 if(wave.period <= 0)
342 usage("Execution behavior period must be a positive number.");
343 break;
344 case 'D':
345 wave.extrema_delay = atoi(optarg);
346 break;
186 case ':': 347 case ':':
187 usage("Argument missing."); 348 usage("Argument missing.");
188 break; 349 break;
@@ -219,6 +380,42 @@ int main(int argc, char** argv)
219 "exceed the period."); 380 "exceed the period.");
220 } 381 }
221 382
383 if(wave.f != NULL)
384 {
385 wave.min_wcet_ms = wcet_ms;
386 wave.amplitude = wave.max_wcet_ms - wave.min_wcet_ms;
387 if(wave.amplitude < 0.0)
388 {
389 usage("The max wcet must be greater than min wcet.");
390 }
391
392 if(wave.f == flat_wave)
393 {
394 wave.max_point = 0;
395 wave.min_point = 0;
396 }
397 else if((wave.f == sin_wave) || (wave.f == tri_wave) || (wave.f == box_wave))
398 {
399 wave.max_point = wave.period/2;
400 wave.min_point = 0;
401 }
402 else if(wave.f == saw_wave)
403 {
404 wave.max_point = wave.period-1;
405 wave.min_point = 0;
406 }
407 else if(wave.f == rsaw_wave)
408 {
409 wave.max_point = 0;
410 wave.min_point = wave.period-1;
411 }
412
413 if((wave.f == flat_wave) || (wave.f == box_wave))
414 {
415 wave.extrema_delay = 0;
416 }
417 }
418
222 if (migrate) { 419 if (migrate) {
223 ret = be_migrate_to(cpu); 420 ret = be_migrate_to(cpu);
224 if (ret < 0) 421 if (ret < 0)
@@ -226,7 +423,7 @@ int main(int argc, char** argv)
226 } 423 }
227 424
228 ret = sporadic_task_ns(wcet, period, 0, 425 ret = sporadic_task_ns(wcet, period, 0,
229 LITMUS_FP_ZERO, LITMUS_FP_ZERO, 426 A, B,
230 cpu, class, 427 cpu, class,
231 want_enforcement ? PRECISE_ENFORCEMENT 428 want_enforcement ? PRECISE_ENFORCEMENT
232 : NO_ENFORCEMENT, 429 : NO_ENFORCEMENT,
@@ -252,8 +449,17 @@ int main(int argc, char** argv)
252 449
253 start = wctime(); 450 start = wctime();
254 451
255 while (start + duration > wctime()) { 452 int count = 0;
256 job(wcet_ms * 0.0009); /* 90% wcet, in seconds */ 453 while (start + duration > wctime())
454 {
455 if(wave.f == NULL)
456 {
457 job(wcet_ms * 0.0009); /* 90% wcet, in seconds */
458 }
459 else
460 {
461 job(get_execution_time(count++, &wave) * 0.0009);
462 }
257 } 463 }
258 464
259 return 0; 465 return 0;