aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--bin/rt_launch.c8
-rw-r--r--bin/rtspin.c19
-rw-r--r--include/litmus.h39
-rw-r--r--src/litmus.c2
-rw-r--r--src/signal.c28
-rw-r--r--src/task.c4
-rw-r--r--tests/fdso.c4
8 files changed, 59 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index d37f076..5760440 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ LITMUS_KERNEL ?= ../litmus-rt
19# Internal configuration. 19# Internal configuration.
20 20
21# compiler flags 21# compiler flags
22flags-debug = -Wall -Werror -g -Wdeclaration-after-statement 22flags-debug = -Wall -Werror -Wdeclaration-after-statement -g
23flags-api = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE 23flags-api = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE
24 24
25# architecture-specific flags 25# architecture-specific flags
diff --git a/bin/rt_launch.c b/bin/rt_launch.c
index 3863031..84a5e6c 100644
--- a/bin/rt_launch.c
+++ b/bin/rt_launch.c
@@ -54,7 +54,7 @@ int main(int argc, char** argv)
54 int verbose = 0; 54 int verbose = 0;
55 int wait = 0; 55 int wait = 0;
56 startup_info_t info; 56 startup_info_t info;
57 task_class_t class = RT_CLASS_HARD; 57 task_class_t rt_class = RT_CLASS_HARD;
58 58
59 while ((opt = getopt(argc, argv, OPTSTR)) != -1) { 59 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
60 switch (opt) { 60 switch (opt) {
@@ -69,8 +69,8 @@ int main(int argc, char** argv)
69 migrate = 1; 69 migrate = 1;
70 break; 70 break;
71 case 'c': 71 case 'c':
72 class = str2class(optarg); 72 rt_class = str2class(optarg);
73 if (class == -1) 73 if (rt_class == -1)
74 usage("Unknown task class."); 74 usage("Unknown task class.");
75 break; 75 break;
76 76
@@ -107,7 +107,7 @@ int main(int argc, char** argv)
107 if (ret < 0) 107 if (ret < 0)
108 bail_out("could not migrate to target partition"); 108 bail_out("could not migrate to target partition");
109 } 109 }
110 ret = __create_rt_task(launch, &info, cpu, wcet, period, class); 110 ret = __create_rt_task(launch, &info, cpu, wcet, period, rt_class);
111 111
112 112
113 if (ret < 0) 113 if (ret < 0)
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 1daed82..8ee26d5 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -67,7 +67,7 @@ static void get_exec_times(const char *file, const int column,
67 bail_out("rewinding file failed"); 67 bail_out("rewinding file failed");
68 68
69 /* allocate space for exec times */ 69 /* allocate space for exec times */
70 *exec_times = calloc(*num_jobs, sizeof(*exec_times)); 70 *exec_times = (double*)calloc(*num_jobs, sizeof(*exec_times));
71 if (!*exec_times) 71 if (!*exec_times)
72 bail_out("couldn't allocate memory"); 72 bail_out("couldn't allocate memory");
73 73
@@ -161,7 +161,7 @@ static int job(double exec_time, double program_end)
161 loop_for(exec_time, program_end + 1); 161 loop_for(exec_time, program_end + 1);
162 } 162 }
163 LITMUS_CATCH(SIG_BUDGET) { 163 LITMUS_CATCH(SIG_BUDGET) {
164 printf("Exhausted budget! Finishing job NOW!\n"); 164 fprintf(stdout, "Exhausted budget! Finishing job NOW!\n");
165 } 165 }
166 END_LITMUS_TRY; 166 END_LITMUS_TRY;
167 } 167 }
@@ -193,7 +193,7 @@ int main(int argc, char** argv)
193 double duration = 0, start; 193 double duration = 0, start;
194 double *exec_times = NULL; 194 double *exec_times = NULL;
195 double scale = 1.0; 195 double scale = 1.0;
196 task_class_t class = RT_CLASS_HARD; 196 task_class_t rt_class = RT_CLASS_HARD;
197 int cur_job, num_jobs; 197 int cur_job, num_jobs;
198 198
199 progname = argv[0]; 199 progname = argv[0];
@@ -208,8 +208,8 @@ int main(int argc, char** argv)
208 migrate = 1; 208 migrate = 1;
209 break; 209 break;
210 case 'c': 210 case 'c':
211 class = str2class(optarg); 211 rt_class = str2class(optarg);
212 if (class == -1) 212 if (rt_class == -1)
213 usage("Unknown task class."); 213 usage("Unknown task class.");
214 break; 214 break;
215 case 'e': 215 case 'e':
@@ -290,7 +290,7 @@ int main(int argc, char** argv)
290 bail_out("could not migrate to target partition"); 290 bail_out("could not migrate to target partition");
291 } 291 }
292 292
293 ret = sporadic_task_ns(wcet, period, 0, cpu, class, 293 ret = sporadic_task_ns(wcet, period, 0, cpu, rt_class,
294 want_enforcement ? PRECISE_ENFORCEMENT 294 want_enforcement ? PRECISE_ENFORCEMENT
295 : NO_ENFORCEMENT, 295 : NO_ENFORCEMENT,
296 want_signals ? PRECISE_SIGNALS 296 want_signals ? PRECISE_SIGNALS
@@ -303,7 +303,7 @@ int main(int argc, char** argv)
303 303
304 if (want_signals) { 304 if (want_signals) {
305 /* bind default longjmp signal handler to SIG_BUDGET. */ 305 /* bind default longjmp signal handler to SIG_BUDGET. */
306 activate_litmus_signals(SIG_BUDGET_MASK, longjmp_on_litmus_signal); 306 activate_litmus_signals(SIG_BUDGET_MASK, longjmp_on_litmus_signal);
307 } 307 }
308 308
309 ret = task_mode(LITMUS_RT_TASK); 309 ret = task_mode(LITMUS_RT_TASK);
@@ -327,7 +327,10 @@ int main(int argc, char** argv)
327 } 327 }
328 } else { 328 } else {
329 /* conver to seconds and scale */ 329 /* conver to seconds and scale */
330 while (job(wcet_ms * 0.001 * scale, start + duration)); 330 int run = 1;
331 while (run) {
332 run = job(wcet_ms * 0.001 * scale, start + duration);
333 }
331 } 334 }
332 335
333 ret = task_mode(BACKGROUND_TASK); 336 ret = task_mode(BACKGROUND_TASK);
diff --git a/include/litmus.h b/include/litmus.h
index c284870..ca8328f 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -144,6 +144,9 @@ int null_call(cycles_t *timestamp);
144 */ 144 */
145struct control_page* get_ctrl_page(void); 145struct control_page* get_ctrl_page(void);
146 146
147
148/* Litmus signal handling */
149
147typedef struct litmus_sigjmp 150typedef struct litmus_sigjmp
148{ 151{
149 sigjmp_buf env; 152 sigjmp_buf env;
@@ -156,12 +159,26 @@ litmus_sigjmp_t* pop_sigjmp(void);
156typedef void (*litmus_sig_handler_t)(int); 159typedef void (*litmus_sig_handler_t)(int);
157typedef void (*litmus_sig_actions_t)(int, siginfo_t *, void *); 160typedef void (*litmus_sig_actions_t)(int, siginfo_t *, void *);
158 161
162/* ignore specified signals. all signals raised while ignored are dropped */
159void ignore_litmus_signals(unsigned long litmus_sig_mask); 163void ignore_litmus_signals(unsigned long litmus_sig_mask);
164
165/* register a handler for the given set of litmus signals */
160void activate_litmus_signals(unsigned long litmus_sig_mask, 166void activate_litmus_signals(unsigned long litmus_sig_mask,
161 litmus_sig_handler_t handler); 167 litmus_sig_handler_t handler);
168
169/* register an action signal handler for a given set of signals */
162void activate_litmus_signal_actions(unsigned long litmus_sig_mask, 170void activate_litmus_signal_actions(unsigned long litmus_sig_mask,
163 litmus_sig_actions_t handler); 171 litmus_sig_actions_t handler);
172
173/* Block a given set of litmus signals. Any signals raised while blocked
174 * are queued and delivered after unblocking. Call ignore_litmus_signals()
175 * before unblocking if you wish to discard these. Blocking may be
176 * useful to protect COTS code in Litmus that may not be able to deal
177 * with exception-raising signals.
178 */
164void block_litmus_signals(unsigned long litmus_sig_mask); 179void block_litmus_signals(unsigned long litmus_sig_mask);
180
181/* Unblock a given set of litmus signals. */
165void unblock_litmus_signals(unsigned long litmus_sig_mask); 182void unblock_litmus_signals(unsigned long litmus_sig_mask);
166 183
167#define SIG_BUDGET_MASK 0x00000001 184#define SIG_BUDGET_MASK 0x00000001
@@ -169,7 +186,9 @@ void unblock_litmus_signals(unsigned long litmus_sig_mask);
169 186
170#define ALL_LITMUS_SIG_MASKS (SIG_BUDGET_MASK) 187#define ALL_LITMUS_SIG_MASKS (SIG_BUDGET_MASK)
171 188
172 189/* Try/Catch structures useful for implementing abortable jobs.
190 * Should only be used in legitimate cases. ;)
191 */
173#define LITMUS_TRY \ 192#define LITMUS_TRY \
174do { \ 193do { \
175 int sigsetjmp_ret_##__FUNCTION__##__LINE__; \ 194 int sigsetjmp_ret_##__FUNCTION__##__LINE__; \
@@ -186,6 +205,10 @@ do { \
186 } /* end if-else-if chain */ \ 205 } /* end if-else-if chain */ \
187} while(0); /* end do from 'LITMUS_TRY' */ 206} while(0); /* end do from 'LITMUS_TRY' */
188 207
208/* Calls siglongjmp(signum). Use with TRY/CATCH.
209 * Example:
210 * activate_litmus_signals(SIG_BUDGET_MASK, longjmp_on_litmus_signal);
211 */
189void longjmp_on_litmus_signal(int signum); 212void longjmp_on_litmus_signal(int signum);
190 213
191#ifdef __cplusplus 214#ifdef __cplusplus
@@ -223,20 +246,20 @@ namespace litmus
223 }; 246 };
224 247
225 /* Must compile your program with "non-call-exception". */ 248 /* Must compile your program with "non-call-exception". */
226 static void throw_on_litmus_signal(int signum) __used__ 249 static __attribute__((used))
250 void throw_on_litmus_signal(int signum)
227 { 251 {
228 printf("WE GET SIGNAL! %d\n", signum);
229 /* We have to unblock the received signal to get more in the future 252 /* We have to unblock the received signal to get more in the future
230 * because we are not calling siglongjmp(), which normally restores 253 * because we are not calling siglongjmp(), which normally restores
231 * the mask for us. 254 * the mask for us.
232 */ 255 */
233 switch(signum) 256 if (SIG_BUDGET == signum) {
234 {
235 case SIG_BUDGET:
236 unblock_litmus_signals(SIG_BUDGET_MASK); 257 unblock_litmus_signals(SIG_BUDGET_MASK);
237 throw sigbudget(); 258 throw sigbudget();
238 default: 259 }
239 ; /* silently ignore */ 260 /* else if (...) */
261 else {
262 /* silently ignore */
240 } 263 }
241 } 264 }
242 265
diff --git a/src/litmus.c b/src/litmus.c
index aaaeee3..0b7c561 100644
--- a/src/litmus.c
+++ b/src/litmus.c
@@ -26,7 +26,7 @@ task_class_t str2class(const char* str)
26 else if (!strcmp(str, "be")) 26 else if (!strcmp(str, "be"))
27 return RT_CLASS_BEST_EFFORT; 27 return RT_CLASS_BEST_EFFORT;
28 else 28 else
29 return -1; 29 return (task_class_t)(-1);
30} 30}
31 31
32#define NS_PER_MS 1000000 32#define NS_PER_MS 1000000
diff --git a/src/signal.c b/src/signal.c
index a98ed78..bfe18b9 100644
--- a/src/signal.c
+++ b/src/signal.c
@@ -4,26 +4,13 @@
4#include "litmus.h" 4#include "litmus.h"
5#include "internal.h" 5#include "internal.h"
6 6
7/* setjmp calls are stored on a singlely link list,
8 * one stack per thread.
9 */
7static __thread litmus_sigjmp_t *g_sigjmp_tail = 0; 10static __thread litmus_sigjmp_t *g_sigjmp_tail = 0;
8 11
9void throw_litmus_signal(int signum)
10{
11 litmus_sigjmp_t *lit_env;
12
13 printf("WE GET SIGNAL!\n");
14 lit_env = pop_sigjmp();
15 if (lit_env) {
16 printf("received signal %d!\n", signum);
17 siglongjmp(lit_env->env, signum);
18 }
19 else {
20 /* silently ignore the signal. */
21 }
22}
23
24void push_sigjmp(litmus_sigjmp_t *buf) 12void push_sigjmp(litmus_sigjmp_t *buf)
25{ 13{
26 printf("push\n");
27 buf->prev = g_sigjmp_tail; 14 buf->prev = g_sigjmp_tail;
28 g_sigjmp_tail = buf; 15 g_sigjmp_tail = buf;
29} 16}
@@ -31,7 +18,6 @@ void push_sigjmp(litmus_sigjmp_t *buf)
31litmus_sigjmp_t* pop_sigjmp(void) 18litmus_sigjmp_t* pop_sigjmp(void)
32{ 19{
33 litmus_sigjmp_t* ret; 20 litmus_sigjmp_t* ret;
34 printf("pop\n");
35 ret = g_sigjmp_tail; 21 ret = g_sigjmp_tail;
36 g_sigjmp_tail = (ret) ? ret->prev : NULL; 22 g_sigjmp_tail = (ret) ? ret->prev : NULL;
37 return ret; 23 return ret;
@@ -46,7 +32,7 @@ static void reg_litmus_signals(unsigned long litmus_sig_mask,
46 ret = sigaction(SIG_BUDGET, pAction, NULL); 32 ret = sigaction(SIG_BUDGET, pAction, NULL);
47 check("SIG_BUDGET"); 33 check("SIG_BUDGET");
48 } 34 }
49 /* more ... */ 35 /* more signals ... */
50} 36}
51 37
52void ignore_litmus_signals(unsigned long litmus_sig_mask) 38void ignore_litmus_signals(unsigned long litmus_sig_mask)
@@ -84,7 +70,7 @@ void block_litmus_signals(unsigned long litmus_sig_mask)
84 if (litmus_sig_mask | SIG_BUDGET_MASK) { 70 if (litmus_sig_mask | SIG_BUDGET_MASK) {
85 sigaddset(&sigs, SIG_BUDGET); 71 sigaddset(&sigs, SIG_BUDGET);
86 } 72 }
87 /* more ... */ 73 /* more signals ... */
88 74
89 ret = sigprocmask(SIG_BLOCK, &sigs, NULL); 75 ret = sigprocmask(SIG_BLOCK, &sigs, NULL);
90 check("SIG_BLOCK litmus signals"); 76 check("SIG_BLOCK litmus signals");
@@ -108,11 +94,11 @@ void unblock_litmus_signals(unsigned long litmus_sig_mask)
108 94
109void longjmp_on_litmus_signal(int signum) 95void longjmp_on_litmus_signal(int signum)
110{ 96{
97 /* We get signal! Main screen turn on! */
111 litmus_sigjmp_t *lit_env; 98 litmus_sigjmp_t *lit_env;
112 printf("WE GET SIGNAL!\n");
113 lit_env = pop_sigjmp(); 99 lit_env = pop_sigjmp();
114 if (lit_env) { 100 if (lit_env) {
115 printf("received signal %d\n", signum); 101 /* What you say?! */
116 siglongjmp(lit_env->env, signum); /* restores signal mask */ 102 siglongjmp(lit_env->env, signum); /* restores signal mask */
117 } 103 }
118 else { 104 else {
diff --git a/src/task.c b/src/task.c
index 4d237bd..26fc15a 100644
--- a/src/task.c
+++ b/src/task.c
@@ -41,13 +41,13 @@ int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, rt_setup_fn_t setup,
41} 41}
42 42
43int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, 43int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period,
44 task_class_t class) 44 task_class_t rt_class)
45{ 45{
46 struct rt_task params; 46 struct rt_task params;
47 params.cpu = cpu; 47 params.cpu = cpu;
48 params.period = period; 48 params.period = period;
49 params.exec_cost = wcet; 49 params.exec_cost = wcet;
50 params.cls = class; 50 params.cls = rt_class;
51 params.phase = 0; 51 params.phase = 0;
52 /* enforce budget for tasks that might not use sleep_next_period() */ 52 /* enforce budget for tasks that might not use sleep_next_period() */
53 params.budget_policy = QUANTUM_ENFORCEMENT; 53 params.budget_policy = QUANTUM_ENFORCEMENT;
diff --git a/tests/fdso.c b/tests/fdso.c
index 8a2a0d0..8e320cf 100644
--- a/tests/fdso.c
+++ b/tests/fdso.c
@@ -48,8 +48,8 @@ TESTCASE(invalid_od, ALL,
48TESTCASE(invalid_obj_type, ALL, 48TESTCASE(invalid_obj_type, ALL,
49 "reject invalid object types") 49 "reject invalid object types")
50{ 50{
51 SYSCALL_FAILS( EINVAL, od_open(0, -1, 0) ); 51 SYSCALL_FAILS( EINVAL, od_open(0, (obj_type_t)-1, 0) );
52 SYSCALL_FAILS( EINVAL, od_open(0, 10, 0) ); 52 SYSCALL_FAILS( EINVAL, od_open(0, (obj_type_t)10, 0) );
53} 53}
54 54
55TESTCASE(not_inherit_od, GSN_EDF | PSN_EDF, 55TESTCASE(not_inherit_od, GSN_EDF | PSN_EDF,