diff options
| author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-09-07 23:22:38 -0400 |
|---|---|---|
| committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-09-07 23:24:15 -0400 |
| commit | 4829f4175482e0a4ad8f282dd0441904c33e2f97 (patch) | |
| tree | 1ea66f39beaa1f1fcad08763eebc90537a403b5f | |
| parent | 12587122ff78adffa2e8bcb571962d8f19365fb9 (diff) | |
Added signal-related comments. Made g++ friendly.prop/litmus-signals
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | bin/rt_launch.c | 8 | ||||
| -rw-r--r-- | bin/rtspin.c | 19 | ||||
| -rw-r--r-- | include/litmus.h | 39 | ||||
| -rw-r--r-- | src/litmus.c | 2 | ||||
| -rw-r--r-- | src/signal.c | 28 | ||||
| -rw-r--r-- | src/task.c | 4 | ||||
| -rw-r--r-- | tests/fdso.c | 4 |
8 files changed, 59 insertions, 47 deletions
| @@ -19,7 +19,7 @@ LITMUS_KERNEL ?= ../litmus-rt | |||
| 19 | # Internal configuration. | 19 | # Internal configuration. |
| 20 | 20 | ||
| 21 | # compiler flags | 21 | # compiler flags |
| 22 | flags-debug = -Wall -Werror -g -Wdeclaration-after-statement | 22 | flags-debug = -Wall -Werror -Wdeclaration-after-statement -g |
| 23 | flags-api = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE | 23 | flags-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 | */ |
| 145 | struct control_page* get_ctrl_page(void); | 145 | struct control_page* get_ctrl_page(void); |
| 146 | 146 | ||
| 147 | |||
| 148 | /* Litmus signal handling */ | ||
| 149 | |||
| 147 | typedef struct litmus_sigjmp | 150 | typedef struct litmus_sigjmp |
| 148 | { | 151 | { |
| 149 | sigjmp_buf env; | 152 | sigjmp_buf env; |
| @@ -156,12 +159,26 @@ litmus_sigjmp_t* pop_sigjmp(void); | |||
| 156 | typedef void (*litmus_sig_handler_t)(int); | 159 | typedef void (*litmus_sig_handler_t)(int); |
| 157 | typedef void (*litmus_sig_actions_t)(int, siginfo_t *, void *); | 160 | typedef void (*litmus_sig_actions_t)(int, siginfo_t *, void *); |
| 158 | 161 | ||
| 162 | /* ignore specified signals. all signals raised while ignored are dropped */ | ||
| 159 | void ignore_litmus_signals(unsigned long litmus_sig_mask); | 163 | void ignore_litmus_signals(unsigned long litmus_sig_mask); |
| 164 | |||
| 165 | /* register a handler for the given set of litmus signals */ | ||
| 160 | void activate_litmus_signals(unsigned long litmus_sig_mask, | 166 | void 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 */ | ||
| 162 | void activate_litmus_signal_actions(unsigned long litmus_sig_mask, | 170 | void 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 | */ | ||
| 164 | void block_litmus_signals(unsigned long litmus_sig_mask); | 179 | void block_litmus_signals(unsigned long litmus_sig_mask); |
| 180 | |||
| 181 | /* Unblock a given set of litmus signals. */ | ||
| 165 | void unblock_litmus_signals(unsigned long litmus_sig_mask); | 182 | void 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 \ |
| 174 | do { \ | 193 | do { \ |
| 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 | */ | ||
| 189 | void longjmp_on_litmus_signal(int signum); | 212 | void 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 | */ | ||
| 7 | static __thread litmus_sigjmp_t *g_sigjmp_tail = 0; | 10 | static __thread litmus_sigjmp_t *g_sigjmp_tail = 0; |
| 8 | 11 | ||
| 9 | void 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 | |||
| 24 | void push_sigjmp(litmus_sigjmp_t *buf) | 12 | void 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) | |||
| 31 | litmus_sigjmp_t* pop_sigjmp(void) | 18 | litmus_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 | ||
| 52 | void ignore_litmus_signals(unsigned long litmus_sig_mask) | 38 | void 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 | ||
| 109 | void longjmp_on_litmus_signal(int signum) | 95 | void 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 { |
| @@ -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 | ||
| 43 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, | 43 | int __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, | |||
| 48 | TESTCASE(invalid_obj_type, ALL, | 48 | TESTCASE(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 | ||
| 55 | TESTCASE(not_inherit_od, GSN_EDF | PSN_EDF, | 55 | TESTCASE(not_inherit_od, GSN_EDF | PSN_EDF, |
