aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-09-10 16:38:25 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-09-10 16:38:25 -0400
commit9bc72959cf8d4750de7f968fc35ea3b7463cad11 (patch)
tree5b75736d9f574bcc47394475bdf8d8060c8497ff
parent12d8c50580f06ba48fd1563508e49fcaabd936d0 (diff)
parent4829f4175482e0a4ad8f282dd0441904c33e2f97 (diff)
Merge remote-tracking branch 'github/prop/litmus-signals' into wip-gpu-rtas12
Conflicts: Makefile
-rw-r--r--Makefile5
-rw-r--r--bin/rt_launch.c8
-rw-r--r--bin/rtspin.c48
-rw-r--r--dgl.c2
-rw-r--r--ikglptest.c50
-rw-r--r--include/litmus.h134
-rw-r--r--nested.c2
-rw-r--r--src/litmus.c13
-rw-r--r--src/signal.c107
-rw-r--r--src/task.c4
-rw-r--r--tests/fdso.c4
11 files changed, 324 insertions, 53 deletions
diff --git a/Makefile b/Makefile
index e99f0dd..e07d39c 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 = -g -std=c99 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
@@ -157,6 +157,7 @@ litmus-headers = \
157 include/litmus/rt_param.h \ 157 include/litmus/rt_param.h \
158 include/litmus/fpmath.h \ 158 include/litmus/fpmath.h \
159 include/litmus/binheap.h \ 159 include/litmus/binheap.h \
160 include/litmus/signal.h \
160 include/litmus/unistd_32.h \ 161 include/litmus/unistd_32.h \
161 include/litmus/unistd_64.h 162 include/litmus/unistd_64.h
162 163
@@ -237,7 +238,7 @@ lib-measure_syscall = -lm
237 238
238.SECONDEXPANSION: 239.SECONDEXPANSION:
239${rt-apps}: $${obj-$$@} liblitmus.a 240${rt-apps}: $${obj-$$@} liblitmus.a
240 $(CC) -o $@ $(LDFLAGS) ${ldf-$@} $(filter-out liblitmus.a,$+) $(LOADLIBS) $(LDLIBS) ${lib-$@} ${liblitmus-flags} ${lib-$@} 241 $(CC) -o $@ $(LDFLAGS) ${ldf-$@} $(filter-out liblitmus.a,$+) $(LOADLIBS) $(LDLIBS) ${liblitmus-flags} ${lib-$@}
241 242
242# ############################################################################## 243# ##############################################################################
243# Dependency resolution. 244# Dependency resolution.
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 ae76941..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
@@ -152,16 +152,28 @@ static void debug_delay_loop(void)
152 152
153static int job(double exec_time, double program_end) 153static int job(double exec_time, double program_end)
154{ 154{
155 if (wctime() > program_end) 155 int exit = 0;
156 return 0; 156 if (wctime() > program_end) {
157 exit = 1;
158 }
157 else { 159 else {
158 loop_for(exec_time, program_end + 1); 160 LITMUS_TRY {
161 loop_for(exec_time, program_end + 1);
162 }
163 LITMUS_CATCH(SIG_BUDGET) {
164 fprintf(stdout, "Exhausted budget! Finishing job NOW!\n");
165 }
166 END_LITMUS_TRY;
167 }
168
169 if (!exit) {
159 sleep_next_period(); 170 sleep_next_period();
160 return 1;
161 } 171 }
172
173 return !exit;
162} 174}
163 175
164#define OPTSTR "p:c:wlveo:f:s:" 176#define OPTSTR "p:c:wlveio:f:s:"
165 177
166int main(int argc, char** argv) 178int main(int argc, char** argv)
167{ 179{
@@ -177,10 +189,11 @@ int main(int argc, char** argv)
177 int column = 1; 189 int column = 1;
178 const char *file = NULL; 190 const char *file = NULL;
179 int want_enforcement = 0; 191 int want_enforcement = 0;
192 int want_signals = 0;
180 double duration = 0, start; 193 double duration = 0, start;
181 double *exec_times = NULL; 194 double *exec_times = NULL;
182 double scale = 1.0; 195 double scale = 1.0;
183 task_class_t class = RT_CLASS_HARD; 196 task_class_t rt_class = RT_CLASS_HARD;
184 int cur_job, num_jobs; 197 int cur_job, num_jobs;
185 198
186 progname = argv[0]; 199 progname = argv[0];
@@ -195,13 +208,16 @@ int main(int argc, char** argv)
195 migrate = 1; 208 migrate = 1;
196 break; 209 break;
197 case 'c': 210 case 'c':
198 class = str2class(optarg); 211 rt_class = str2class(optarg);
199 if (class == -1) 212 if (rt_class == -1)
200 usage("Unknown task class."); 213 usage("Unknown task class.");
201 break; 214 break;
202 case 'e': 215 case 'e':
203 want_enforcement = 1; 216 want_enforcement = 1;
204 break; 217 break;
218 case 'i':
219 want_signals = 1;
220 break;
205 case 'l': 221 case 'l':
206 test_loop = 1; 222 test_loop = 1;
207 break; 223 break;
@@ -274,15 +290,22 @@ int main(int argc, char** argv)
274 bail_out("could not migrate to target partition"); 290 bail_out("could not migrate to target partition");
275 } 291 }
276 292
277 ret = sporadic_task_ns(wcet, period, 0, cpu, class, 293 ret = sporadic_task_ns(wcet, period, 0, cpu, rt_class,
278 want_enforcement ? PRECISE_ENFORCEMENT 294 want_enforcement ? PRECISE_ENFORCEMENT
279 : NO_ENFORCEMENT, 295 : NO_ENFORCEMENT,
296 want_signals ? PRECISE_SIGNALS
297 : NO_SIGNALS,
280 migrate); 298 migrate);
281 if (ret < 0) 299 if (ret < 0)
282 bail_out("could not setup rt task params"); 300 bail_out("could not setup rt task params");
283 301
284 init_litmus(); 302 init_litmus();
285 303
304 if (want_signals) {
305 /* bind default longjmp signal handler to SIG_BUDGET. */
306 activate_litmus_signals(SIG_BUDGET_MASK, longjmp_on_litmus_signal);
307 }
308
286 ret = task_mode(LITMUS_RT_TASK); 309 ret = task_mode(LITMUS_RT_TASK);
287 if (ret != 0) 310 if (ret != 0)
288 bail_out("could not become RT task"); 311 bail_out("could not become RT task");
@@ -304,7 +327,10 @@ int main(int argc, char** argv)
304 } 327 }
305 } else { 328 } else {
306 /* conver to seconds and scale */ 329 /* conver to seconds and scale */
307 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 }
308 } 334 }
309 335
310 ret = task_mode(BACKGROUND_TASK); 336 ret = task_mode(BACKGROUND_TASK);
diff --git a/dgl.c b/dgl.c
index d2317f5..3870a03 100644
--- a/dgl.c
+++ b/dgl.c
@@ -149,7 +149,7 @@ void* rt_thread(void* _ctx)
149 TH_CALL( init_rt_thread() ); 149 TH_CALL( init_rt_thread() );
150 150
151 /* Vary period a little bit. */ 151 /* Vary period a little bit. */
152 TH_CALL( sporadic_task_ns(EXEC_COST, PERIOD + 10*ctx->id, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, 0) ); 152 TH_CALL( sporadic_task_ns(EXEC_COST, PERIOD + 10*ctx->id, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, NO_SIGNALS, 0) );
153 153
154 ctx->ikglp = open_ikglp_sem(ctx->fd, 0, (void*)&NUM_REPLICAS); 154 ctx->ikglp = open_ikglp_sem(ctx->fd, 0, (void*)&NUM_REPLICAS);
155 if(ctx->ikglp < 0) 155 if(ctx->ikglp < 0)
diff --git a/ikglptest.c b/ikglptest.c
index 8c1ac0b..8e088c1 100644
--- a/ikglptest.c
+++ b/ikglptest.c
@@ -109,7 +109,7 @@ struct avg_info feedback(int _a, int _b)
109 fp_t _est, _err; 109 fp_t _est, _err;
110 110
111 int base = 1000000; 111 int base = 1000000;
112 int range = 40; 112 //int range = 40;
113 113
114 fp_t est = _integer_to_fp(base); 114 fp_t est = _integer_to_fp(base);
115 fp_t err = _fp(base/2); 115 fp_t err = _fp(base/2);
@@ -117,50 +117,56 @@ struct avg_info feedback(int _a, int _b)
117#define NUM_SAMPLES 10000 117#define NUM_SAMPLES 10000
118 118
119 float samples[NUM_SAMPLES] = {0.0}; 119 float samples[NUM_SAMPLES] = {0.0};
120 120 float accu_abs, accu;
121 float avg;
122 float devsum;
123 float stdev;
124 struct avg_info ret;
121 125
122 for(i = 0; i < NUM_SAMPLES; ++i) { 126 for(i = 0; i < NUM_SAMPLES; ++i) {
123 int num = ((rand()%40)*(rand()%2 ? -1 : 1)/100.0)*base + base; 127 int num = ((rand()%40)*(rand()%2 ? -1 : 1)/100.0)*base + base;
124 actual_fp = _integer_to_fp(num); 128 float rel_err;
129
130 actual_fp = _integer_to_fp(num);
125 131
126// printf("Before: est = %d\terr = %d\n", (int)_fp_to_integer(est), (int)_fp_to_integer(err)); 132// printf("Before: est = %d\terr = %d\n", (int)_fp_to_integer(est), (int)_fp_to_integer(err));
127 133
128 _err = _sub(actual_fp, est); 134 _err = _sub(actual_fp, est);
129 _est = _add(_mul(a, _err), _mul(b, err)); 135 _est = _add(_mul(a, _err), _mul(b, err));
130 136
131 float rel_err = _fp_to_integer(_mul(_div(_err, est), _integer_to_fp(10000)))/10000.0; 137 rel_err = _fp_to_integer(_mul(_div(_err, est), _integer_to_fp(10000)))/10000.0;
132 rel_err *= 100.0; 138 rel_err *= 100.0;
133 //printf("%6.2f\n", rel_err); 139 //printf("%6.2f\n", rel_err);
134 samples[i] = rel_err; 140 samples[i] = rel_err;
135 141
136 est = _est; 142 est = _est;
137 err = _add(err, _err); 143 err = _add(err, _err);
138 144
139 if((int)_fp_to_integer(est) <= 0) { 145 if((int)_fp_to_integer(est) <= 0) {
140 est = actual_fp; 146 est = actual_fp;
141 err = _div(actual_fp, _integer_to_fp(2)); 147 err = _div(actual_fp, _integer_to_fp(2));
142 } 148 }
143 149
144 //printf("After: est = %d\terr = %d\n", (int)_fp_to_integer(est), (int)_fp_to_integer(err)); 150 //printf("After: est = %d\terr = %d\n", (int)_fp_to_integer(est), (int)_fp_to_integer(err));
145 } 151 }
146 152
147 float accu_abs = 0.0, accu = 0.0; 153 accu_abs = 0.0;
154 accu = 0.0;
148 for(i = 0; i < NUM_SAMPLES; ++i) { 155 for(i = 0; i < NUM_SAMPLES; ++i) {
149 accu += samples[i]; 156 accu += samples[i];
150 accu_abs += abs(samples[i]); 157 accu_abs += abs(samples[i]);
151 } 158 }
152 159
153 float avg = accu_abs/NUM_SAMPLES; 160 avg = accu_abs/NUM_SAMPLES;
154 float devsum = 0; 161 devsum = 0;
155 for(i = 0; i < NUM_SAMPLES; ++i) { 162 for(i = 0; i < NUM_SAMPLES; ++i) {
156 float dev = samples[i] - avg; 163 float dev = samples[i] - avg;
157 dev *= dev; 164 dev *= dev;
158 devsum += dev; 165 devsum += dev;
159 } 166 }
160 167
161 float stdev = sqrtf(devsum/(NUM_SAMPLES-1)); 168 stdev = sqrtf(devsum/(NUM_SAMPLES-1));
162 169
163 struct avg_info ret;
164 ret.avg = avg; 170 ret.avg = avg;
165 ret.stdev = stdev; 171 ret.stdev = stdev;
166 172
@@ -381,7 +387,7 @@ void* rt_thread(void* _ctx)
381 TH_CALL( init_rt_thread() ); 387 TH_CALL( init_rt_thread() );
382 388
383 /* Vary period a little bit. */ 389 /* Vary period a little bit. */
384 TH_CALL( sporadic_task_ns(EXEC_COST, PERIOD + 10*ctx->id, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, 1) ); 390 TH_CALL( sporadic_task_ns(EXEC_COST, PERIOD + 10*ctx->id, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, NO_SIGNALS, 1) );
385 391
386 if(USE_KFMLP) { 392 if(USE_KFMLP) {
387 ctx->kexclu = open_kfmlp_gpu_sem(ctx->fd, 393 ctx->kexclu = open_kfmlp_gpu_sem(ctx->fd,
diff --git a/include/litmus.h b/include/litmus.h
index 2e26868..c3ef941 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -7,12 +7,14 @@ extern "C" {
7 7
8#include <sys/types.h> 8#include <sys/types.h>
9#include <stdint.h> 9#include <stdint.h>
10#include <setjmp.h>
10 11
11/* Include kernel header. 12/* Include kernel header.
12 * This is required for the rt_param 13 * This is required for the rt_param
13 * and control_page structures. 14 * and control_page structures.
14 */ 15 */
15#include "litmus/rt_param.h" 16#include "litmus/rt_param.h"
17#include "litmus/signal.h"
16 18
17#include "asm/cycles.h" /* for null_call() */ 19#include "asm/cycles.h" /* for null_call() */
18 20
@@ -33,19 +35,23 @@ int get_rt_task_param(pid_t pid, struct rt_task* param);
33int sporadic_task( 35int sporadic_task(
34 lt_t e, lt_t p, lt_t phase, 36 lt_t e, lt_t p, lt_t phase,
35 int partition, task_class_t cls, 37 int partition, task_class_t cls,
36 budget_policy_t budget_policy, int set_cpu_set); 38 budget_policy_t budget_policy,
39 budget_signal_policy_t budget_signal_policy,
40 int set_cpu_set);
37 41
38/* times are given in ns */ 42/* times are given in ns */
39int sporadic_task_ns( 43int sporadic_task_ns(
40 lt_t e, lt_t p, lt_t phase, 44 lt_t e, lt_t p, lt_t phase,
41 int cpu, task_class_t cls, 45 int cpu, task_class_t cls,
42 budget_policy_t budget_policy, int set_cpu_set); 46 budget_policy_t budget_policy,
47 budget_signal_policy_t budget_signal_policy,
48 int set_cpu_set);
43 49
44/* budget enforcement off by default in these macros */ 50/* budget enforcement off by default in these macros */
45#define sporadic_global(e, p) \ 51#define sporadic_global(e, p) \
46 sporadic_task(e, p, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, 0) 52 sporadic_task(e, p, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, NO_SIGNALS, 0)
47#define sporadic_partitioned(e, p, cpu) \ 53#define sporadic_partitioned(e, p, cpu) \
48 sporadic_task(e, p, 0, cpu, RT_CLASS_SOFT, NO_ENFORCEMENT, 1) 54 sporadic_task(e, p, 0, cpu, RT_CLASS_SOFT, NO_ENFORCEMENT, NO_SIGNALS, 1)
49 55
50/* file descriptor attached shared objects support */ 56/* file descriptor attached shared objects support */
51typedef enum { 57typedef enum {
@@ -199,7 +205,127 @@ int null_call(cycles_t *timestamp);
199 */ 205 */
200struct control_page* get_ctrl_page(void); 206struct control_page* get_ctrl_page(void);
201 207
208
209/* Litmus signal handling */
210
211typedef struct litmus_sigjmp
212{
213 sigjmp_buf env;
214 struct litmus_sigjmp *prev;
215} litmus_sigjmp_t;
216
217void push_sigjmp(litmus_sigjmp_t* buf);
218litmus_sigjmp_t* pop_sigjmp(void);
219
220typedef void (*litmus_sig_handler_t)(int);
221typedef void (*litmus_sig_actions_t)(int, siginfo_t *, void *);
222
223/* ignore specified signals. all signals raised while ignored are dropped */
224void ignore_litmus_signals(unsigned long litmus_sig_mask);
225
226/* register a handler for the given set of litmus signals */
227void activate_litmus_signals(unsigned long litmus_sig_mask,
228 litmus_sig_handler_t handler);
229
230/* register an action signal handler for a given set of signals */
231void activate_litmus_signal_actions(unsigned long litmus_sig_mask,
232 litmus_sig_actions_t handler);
233
234/* Block a given set of litmus signals. Any signals raised while blocked
235 * are queued and delivered after unblocking. Call ignore_litmus_signals()
236 * before unblocking if you wish to discard these. Blocking may be
237 * useful to protect COTS code in Litmus that may not be able to deal
238 * with exception-raising signals.
239 */
240void block_litmus_signals(unsigned long litmus_sig_mask);
241
242/* Unblock a given set of litmus signals. */
243void unblock_litmus_signals(unsigned long litmus_sig_mask);
244
245#define SIG_BUDGET_MASK 0x00000001
246/* more ... */
247
248#define ALL_LITMUS_SIG_MASKS (SIG_BUDGET_MASK)
249
250/* Try/Catch structures useful for implementing abortable jobs.
251 * Should only be used in legitimate cases. ;)
252 */
253#define LITMUS_TRY \
254do { \
255 int sigsetjmp_ret_##__FUNCTION__##__LINE__; \
256 litmus_sigjmp_t lit_env_##__FUNCTION__##__LINE__; \
257 push_sigjmp(&lit_env_##__FUNCTION__##__LINE__); \
258 sigsetjmp_ret_##__FUNCTION__##__LINE__ = \
259 sigsetjmp(lit_env_##__FUNCTION__##__LINE__.env, 1); \
260 if (sigsetjmp_ret_##__FUNCTION__##__LINE__ == 0) {
261
262#define LITMUS_CATCH(x) \
263 } else if (sigsetjmp_ret_##__FUNCTION__##__LINE__ == (x)) {
264
265#define END_LITMUS_TRY \
266 } /* end if-else-if chain */ \
267} while(0); /* end do from 'LITMUS_TRY' */
268
269/* Calls siglongjmp(signum). Use with TRY/CATCH.
270 * Example:
271 * activate_litmus_signals(SIG_BUDGET_MASK, longjmp_on_litmus_signal);
272 */
273void longjmp_on_litmus_signal(int signum);
274
202#ifdef __cplusplus 275#ifdef __cplusplus
203} 276}
204#endif 277#endif
278
279
280
281
282#ifdef __cplusplus
283/* Expose litmus exceptions if C++.
284 *
285 * KLUDGE: We define everything in the header since liblitmus is a C-only
286 * library, but this header could be included in C++ code.
287 */
288
289#include <exception>
290
291namespace litmus
292{
293 class litmus_exception: public std::exception
294 {
295 public:
296 litmus_exception() throw() {}
297 virtual ~litmus_exception() throw() {}
298 virtual const char* what() const throw() { return "litmus_exception";}
299 };
300
301 class sigbudget: public litmus_exception
302 {
303 public:
304 sigbudget() throw() {}
305 virtual ~sigbudget() throw() {}
306 virtual const char* what() const throw() { return "sigbudget"; }
307 };
308
309 /* Must compile your program with "non-call-exception". */
310 static __attribute__((used))
311 void throw_on_litmus_signal(int signum)
312 {
313 /* We have to unblock the received signal to get more in the future
314 * because we are not calling siglongjmp(), which normally restores
315 * the mask for us.
316 */
317 if (SIG_BUDGET == signum) {
318 unblock_litmus_signals(SIG_BUDGET_MASK);
319 throw sigbudget();
320 }
321 /* else if (...) */
322 else {
323 /* silently ignore */
324 }
325 }
326
327}; /* end namespace 'litmus' */
328
329#endif /* end __cplusplus */
330
205#endif 331#endif
diff --git a/nested.c b/nested.c
index 045e170..39c3df6 100644
--- a/nested.c
+++ b/nested.c
@@ -147,7 +147,7 @@ void* rt_thread(void* _ctx)
147 //printf("RT Thread %d active.\n", ctx->id); 147 //printf("RT Thread %d active.\n", ctx->id);
148 148
149 TH_CALL( init_rt_thread() ); 149 TH_CALL( init_rt_thread() );
150 TH_CALL( sporadic_task_ns(EXEC_COST, PERIOD + 10*ctx->id, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, 0) ); 150 TH_CALL( sporadic_task_ns(EXEC_COST, PERIOD + 10*ctx->id, 0, 0, RT_CLASS_SOFT, NO_ENFORCEMENT, NO_SIGNALS, 0) );
151 151
152 for (i = 0; i < NUM_SEMS; i++) { 152 for (i = 0; i < NUM_SEMS; i++) {
153 ctx->od[i] = open_rsm_sem(ctx->fd, i); 153 ctx->od[i] = open_rsm_sem(ctx->fd, i);
diff --git a/src/litmus.c b/src/litmus.c
index 4f404e2..3bab483 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
@@ -43,15 +43,19 @@ int be_migrate_to(int target_cpu)
43 43
44int sporadic_task(lt_t e, lt_t p, lt_t phase, 44int sporadic_task(lt_t e, lt_t p, lt_t phase,
45 int cpu, task_class_t cls, 45 int cpu, task_class_t cls,
46 budget_policy_t budget_policy, int set_cpu_set) 46 budget_policy_t budget_policy,
47 budget_signal_policy_t budget_signal_policy,
48 int set_cpu_set)
47{ 49{
48 return sporadic_task_ns(e * NS_PER_MS, p * NS_PER_MS, phase * NS_PER_MS, 50 return sporadic_task_ns(e * NS_PER_MS, p * NS_PER_MS, phase * NS_PER_MS,
49 cpu, cls, budget_policy, set_cpu_set); 51 cpu, cls, budget_policy, budget_signal_policy, set_cpu_set);
50} 52}
51 53
52int sporadic_task_ns(lt_t e, lt_t p, lt_t phase, 54int sporadic_task_ns(lt_t e, lt_t p, lt_t phase,
53 int cpu, task_class_t cls, 55 int cpu, task_class_t cls,
54 budget_policy_t budget_policy, int set_cpu_set) 56 budget_policy_t budget_policy,
57 budget_signal_policy_t budget_signal_policy,
58 int set_cpu_set)
55{ 59{
56 struct rt_task param; 60 struct rt_task param;
57 int ret; 61 int ret;
@@ -67,6 +71,7 @@ int sporadic_task_ns(lt_t e, lt_t p, lt_t phase,
67 param.cls = cls; 71 param.cls = cls;
68 param.phase = phase; 72 param.phase = phase;
69 param.budget_policy = budget_policy; 73 param.budget_policy = budget_policy;
74 param.budget_signal_policy = budget_signal_policy;
70 75
71 if (set_cpu_set) { 76 if (set_cpu_set) {
72 ret = be_migrate_to(cpu); 77 ret = be_migrate_to(cpu);
diff --git a/src/signal.c b/src/signal.c
new file mode 100644
index 0000000..bfe18b9
--- /dev/null
+++ b/src/signal.c
@@ -0,0 +1,107 @@
1#include <stdio.h>
2#include <string.h>
3
4#include "litmus.h"
5#include "internal.h"
6
7/* setjmp calls are stored on a singlely link list,
8 * one stack per thread.
9 */
10static __thread litmus_sigjmp_t *g_sigjmp_tail = 0;
11
12void push_sigjmp(litmus_sigjmp_t *buf)
13{
14 buf->prev = g_sigjmp_tail;
15 g_sigjmp_tail = buf;
16}
17
18litmus_sigjmp_t* pop_sigjmp(void)
19{
20 litmus_sigjmp_t* ret;
21 ret = g_sigjmp_tail;
22 g_sigjmp_tail = (ret) ? ret->prev : NULL;
23 return ret;
24}
25
26static void reg_litmus_signals(unsigned long litmus_sig_mask,
27 struct sigaction *pAction)
28{
29 int ret;
30
31 if (litmus_sig_mask | SIG_BUDGET_MASK) {
32 ret = sigaction(SIG_BUDGET, pAction, NULL);
33 check("SIG_BUDGET");
34 }
35 /* more signals ... */
36}
37
38void ignore_litmus_signals(unsigned long litmus_sig_mask)
39{
40 activate_litmus_signals(litmus_sig_mask, SIG_IGN);
41}
42
43void activate_litmus_signals(unsigned long litmus_sig_mask,
44 litmus_sig_handler_t handle)
45{
46 struct sigaction action;
47 memset(&action, 0, sizeof(action));
48 action.sa_handler = handle;
49
50 reg_litmus_signals(litmus_sig_mask, &action);
51}
52
53void activate_litmus_signal_actions(unsigned long litmus_sig_mask,
54 litmus_sig_actions_t handle)
55{
56 struct sigaction action;
57 memset(&action, 0, sizeof(action));
58 action.sa_sigaction = handle;
59 action.sa_flags = SA_SIGINFO;
60
61 reg_litmus_signals(litmus_sig_mask, &action);
62}
63
64void block_litmus_signals(unsigned long litmus_sig_mask)
65{
66 int ret;
67 sigset_t sigs;
68 sigemptyset(&sigs);
69
70 if (litmus_sig_mask | SIG_BUDGET_MASK) {
71 sigaddset(&sigs, SIG_BUDGET);
72 }
73 /* more signals ... */
74
75 ret = sigprocmask(SIG_BLOCK, &sigs, NULL);
76 check("SIG_BLOCK litmus signals");
77}
78
79void unblock_litmus_signals(unsigned long litmus_sig_mask)
80{
81 int ret;
82 sigset_t sigs;
83 sigemptyset(&sigs);
84
85 if (litmus_sig_mask | SIG_BUDGET_MASK) {
86 sigaddset(&sigs, SIG_BUDGET);
87 }
88 /* more ... */
89
90 ret = sigprocmask(SIG_UNBLOCK, &sigs, NULL);
91 check("SIG_UNBLOCK litmus signals");
92}
93
94
95void longjmp_on_litmus_signal(int signum)
96{
97 /* We get signal! Main screen turn on! */
98 litmus_sigjmp_t *lit_env;
99 lit_env = pop_sigjmp();
100 if (lit_env) {
101 /* What you say?! */
102 siglongjmp(lit_env->env, signum); /* restores signal mask */
103 }
104 else {
105 /* silently ignore the signal */
106 }
107}
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,