diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-11-06 16:54:09 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-11-09 16:35:33 -0500 |
commit | a957bc576d0bdab19f41d367dc662acd3bb82ae9 (patch) | |
tree | cb531abba443ec03989269723bb85f6dbfa6cb5e | |
parent | d28f0587149ab3086e3978c1251909c1742e6240 (diff) |
add emergency exit to rtspin
This should only trigger if the execution time tracking is broken (as
it was on District10). With the emergency exit, we at least prevent
the system from becoming unresponsive.
-rw-r--r-- | bin/rtspin.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/bin/rtspin.c b/bin/rtspin.c index 33919b1..5e45fb7 100644 --- a/bin/rtspin.c +++ b/bin/rtspin.c | |||
@@ -48,10 +48,10 @@ static int loop_once(void) | |||
48 | return j; | 48 | return j; |
49 | } | 49 | } |
50 | 50 | ||
51 | static int loop_for(double exec_time) | 51 | static int loop_for(double exec_time, double emergency_exit) |
52 | { | 52 | { |
53 | double t = 0; | 53 | double t = 0; |
54 | int tmp = 0; | 54 | int tmp = 0; |
55 | /* while (t + loop_length < exec_time) { | 55 | /* while (t + loop_length < exec_time) { |
56 | tmp += loop_once(); | 56 | tmp += loop_once(); |
57 | t += loop_length; | 57 | t += loop_length; |
@@ -63,6 +63,13 @@ static int loop_for(double exec_time) | |||
63 | tmp += loop_once(); | 63 | tmp += loop_once(); |
64 | t += loop_length; | 64 | t += loop_length; |
65 | now = cputime(); | 65 | now = cputime(); |
66 | if (emergency_exit && wctime() > emergency_exit) { | ||
67 | /* Oops --- this should only be possible if the execution time tracking | ||
68 | * is broken in the LITMUS^RT kernel. */ | ||
69 | fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); | ||
70 | fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); | ||
71 | break; | ||
72 | } | ||
66 | } | 73 | } |
67 | 74 | ||
68 | return tmp; | 75 | return tmp; |
@@ -73,7 +80,7 @@ static void fine_tune(double interval) | |||
73 | double start, end, delta; | 80 | double start, end, delta; |
74 | 81 | ||
75 | start = wctime(); | 82 | start = wctime(); |
76 | loop_for(interval); | 83 | loop_for(interval, 0); |
77 | end = wctime(); | 84 | end = wctime(); |
78 | delta = (end - start - interval) / interval; | 85 | delta = (end - start - interval) / interval; |
79 | if (delta != 0) | 86 | if (delta != 0) |
@@ -115,7 +122,7 @@ static void debug_delay_loop(void) | |||
115 | while (1) { | 122 | while (1) { |
116 | for (delay = 0.5; delay > 0.01; delay -= 0.01) { | 123 | for (delay = 0.5; delay > 0.01; delay -= 0.01) { |
117 | start = wctime(); | 124 | start = wctime(); |
118 | loop_for(delay); | 125 | loop_for(delay, 0); |
119 | end = wctime(); | 126 | end = wctime(); |
120 | printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n", | 127 | printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n", |
121 | delay, | 128 | delay, |
@@ -126,11 +133,15 @@ static void debug_delay_loop(void) | |||
126 | } | 133 | } |
127 | } | 134 | } |
128 | 135 | ||
129 | static int job(double exec_time) | 136 | static int job(double exec_time, double program_end) |
130 | { | 137 | { |
131 | loop_for(exec_time); | 138 | if (wctime() > program_end) |
132 | sleep_next_period(); | 139 | return 0; |
133 | return 0; | 140 | else { |
141 | loop_for(exec_time, program_end + 1); | ||
142 | sleep_next_period(); | ||
143 | return 1; | ||
144 | } | ||
134 | } | 145 | } |
135 | 146 | ||
136 | #define OPTSTR "p:c:wld:ve" | 147 | #define OPTSTR "p:c:wld:ve" |
@@ -250,9 +261,8 @@ int main(int argc, char** argv) | |||
250 | 261 | ||
251 | start = wctime(); | 262 | start = wctime(); |
252 | 263 | ||
253 | while (start + duration > wctime()) { | 264 | /* 90% wcet, in seconds */ |
254 | job(wcet_ms * 0.0009); /* 90% wcet, in seconds */ | 265 | while (job(wcet_ms * 0.0009, start + duration)); |
255 | } | ||
256 | 266 | ||
257 | return 0; | 267 | return 0; |
258 | } | 268 | } |