aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-09-07 19:28:33 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-09-07 19:28:33 -0400
commit0d7304546493b31f1e454191c33a5f95e92b4b57 (patch)
tree98b4e90f833630a88f252a029f00459bde8f144d /src
parent8ee9ebd4b2eb92b7a6060f9f0cd9c95ae087c7e6 (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.c121
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
7static __thread litmus_sigjmp_t *g_sigjmp_tail = 0;
8
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)
25{
26 printf("push\n");
27 buf->prev = g_sigjmp_tail;
28 g_sigjmp_tail = buf;
29}
30
31litmus_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
40static 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
52void ignore_litmus_signals(unsigned long litmus_sig_mask)
53{
54 activate_litmus_signals(litmus_sig_mask, SIG_IGN);
55}
56
57void 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
67void 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
78void 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
93void 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
109void 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}