diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-09-07 19:28:33 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-09-07 19:28:33 -0400 |
commit | 0d7304546493b31f1e454191c33a5f95e92b4b57 (patch) | |
tree | 98b4e90f833630a88f252a029f00459bde8f144d /src | |
parent | 8ee9ebd4b2eb92b7a6060f9f0cd9c95ae087c7e6 (diff) |
Enable handling of Litmus signals.
Add support for handling Litmus-specific signals. Includes
framework try/catch-style handling of signals.
SIG_BUDGET is the only Litmus signal at the moment.
Diffstat (limited to 'src')
-rw-r--r-- | src/signal.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/signal.c b/src/signal.c new file mode 100644 index 0000000..a98ed78 --- /dev/null +++ b/src/signal.c | |||
@@ -0,0 +1,121 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | |||
4 | #include "litmus.h" | ||
5 | #include "internal.h" | ||
6 | |||
7 | static __thread litmus_sigjmp_t *g_sigjmp_tail = 0; | ||
8 | |||
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) | ||
25 | { | ||
26 | printf("push\n"); | ||
27 | buf->prev = g_sigjmp_tail; | ||
28 | g_sigjmp_tail = buf; | ||
29 | } | ||
30 | |||
31 | litmus_sigjmp_t* pop_sigjmp(void) | ||
32 | { | ||
33 | litmus_sigjmp_t* ret; | ||
34 | printf("pop\n"); | ||
35 | ret = g_sigjmp_tail; | ||
36 | g_sigjmp_tail = (ret) ? ret->prev : NULL; | ||
37 | return ret; | ||
38 | } | ||
39 | |||
40 | static void reg_litmus_signals(unsigned long litmus_sig_mask, | ||
41 | struct sigaction *pAction) | ||
42 | { | ||
43 | int ret; | ||
44 | |||
45 | if (litmus_sig_mask | SIG_BUDGET_MASK) { | ||
46 | ret = sigaction(SIG_BUDGET, pAction, NULL); | ||
47 | check("SIG_BUDGET"); | ||
48 | } | ||
49 | /* more ... */ | ||
50 | } | ||
51 | |||
52 | void ignore_litmus_signals(unsigned long litmus_sig_mask) | ||
53 | { | ||
54 | activate_litmus_signals(litmus_sig_mask, SIG_IGN); | ||
55 | } | ||
56 | |||
57 | void activate_litmus_signals(unsigned long litmus_sig_mask, | ||
58 | litmus_sig_handler_t handle) | ||
59 | { | ||
60 | struct sigaction action; | ||
61 | memset(&action, 0, sizeof(action)); | ||
62 | action.sa_handler = handle; | ||
63 | |||
64 | reg_litmus_signals(litmus_sig_mask, &action); | ||
65 | } | ||
66 | |||
67 | void activate_litmus_signal_actions(unsigned long litmus_sig_mask, | ||
68 | litmus_sig_actions_t handle) | ||
69 | { | ||
70 | struct sigaction action; | ||
71 | memset(&action, 0, sizeof(action)); | ||
72 | action.sa_sigaction = handle; | ||
73 | action.sa_flags = SA_SIGINFO; | ||
74 | |||
75 | reg_litmus_signals(litmus_sig_mask, &action); | ||
76 | } | ||
77 | |||
78 | void block_litmus_signals(unsigned long litmus_sig_mask) | ||
79 | { | ||
80 | int ret; | ||
81 | sigset_t sigs; | ||
82 | sigemptyset(&sigs); | ||
83 | |||
84 | if (litmus_sig_mask | SIG_BUDGET_MASK) { | ||
85 | sigaddset(&sigs, SIG_BUDGET); | ||
86 | } | ||
87 | /* more ... */ | ||
88 | |||
89 | ret = sigprocmask(SIG_BLOCK, &sigs, NULL); | ||
90 | check("SIG_BLOCK litmus signals"); | ||
91 | } | ||
92 | |||
93 | void unblock_litmus_signals(unsigned long litmus_sig_mask) | ||
94 | { | ||
95 | int ret; | ||
96 | sigset_t sigs; | ||
97 | sigemptyset(&sigs); | ||
98 | |||
99 | if (litmus_sig_mask | SIG_BUDGET_MASK) { | ||
100 | sigaddset(&sigs, SIG_BUDGET); | ||
101 | } | ||
102 | /* more ... */ | ||
103 | |||
104 | ret = sigprocmask(SIG_UNBLOCK, &sigs, NULL); | ||
105 | check("SIG_UNBLOCK litmus signals"); | ||
106 | } | ||
107 | |||
108 | |||
109 | void longjmp_on_litmus_signal(int signum) | ||
110 | { | ||
111 | litmus_sigjmp_t *lit_env; | ||
112 | printf("WE GET SIGNAL!\n"); | ||
113 | lit_env = pop_sigjmp(); | ||
114 | if (lit_env) { | ||
115 | printf("received signal %d\n", signum); | ||
116 | siglongjmp(lit_env->env, signum); /* restores signal mask */ | ||
117 | } | ||
118 | else { | ||
119 | /* silently ignore the signal */ | ||
120 | } | ||
121 | } | ||