ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_signal.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "signal.hpp"
4#include "cadical.hpp"
5#include "resources.hpp"
6
7/*------------------------------------------------------------------------*/
8
9#include <cassert>
10#include <csignal>
11
12/*------------------------------------------------------------------------*/
13
14#ifndef WIN32
15extern "C" {
16#include <unistd.h>
17}
18#endif
19
21
22/*------------------------------------------------------------------------*/
23
24// Signal handlers for printing statistics even if solver is interrupted.
25
26namespace CaDiCaL {
27
28static volatile bool caught_signal = false;
29static Handler *signal_handler;
30
31#ifndef WIN32
32
33static volatile bool caught_alarm = false;
34static volatile bool alarm_set = false;
35static int alarm_time = -1;
36
37void Handler::catch_alarm () { catch_signal (SIGALRM); }
38
39#endif
40
41#define SIGNALS \
42 SIGNAL (SIGABRT) \
43 SIGNAL (SIGINT) \
44 SIGNAL (SIGSEGV) \
45 SIGNAL (SIGTERM)
46
47#define SIGNAL(SIG) static void (*SIG##_handler) (int);
49#undef SIGNAL
50
51#ifndef WIN32
52
53static void (*SIGALRM_handler) (int);
54
56 if (!alarm_set)
57 return;
58 (void) signal (SIGALRM, SIGALRM_handler);
59 SIGALRM_handler = 0;
60 caught_alarm = false;
61 alarm_set = false;
62 alarm_time = -1;
63}
64
65#endif
66
68 signal_handler = 0;
69#define SIGNAL(SIG) \
70 (void) signal (SIG, SIG##_handler); \
71 SIG##_handler = 0;
73#undef SIGNAL
74#ifndef WIN32
75 reset_alarm ();
76#endif
77 caught_signal = false;
78}
79
80const char *Signal::name (int sig) {
81#define SIGNAL(SIG) \
82 if (sig == SIG) \
83 return #SIG;
85#undef SIGNAL
86#ifndef WIN32
87 if (sig == SIGALRM)
88 return "SIGALRM";
89#endif
90 return "UNKNOWN";
91}
92
93// TODO printing is not reentrant and might lead to deadlock if the signal
94// is raised during another print attempt (and locked IO is used). To avoid
95// this we have to either run our own low-level printing routine here or in
96// 'Message' or just dump those statistics somewhere else were we have
97// exclusive access to. All these solutions are painful and not elegant.
98
99static void catch_signal (int sig) {
100#ifndef WIN32
101 if (sig == SIGALRM && absolute_real_time () >= alarm_time) {
102 if (!caught_alarm) {
103 caught_alarm = true;
104 if (signal_handler)
105 signal_handler->catch_alarm ();
106 }
108 } else
109#endif
110 {
111 if (!caught_signal) {
112 caught_signal = true;
113 if (signal_handler)
114 signal_handler->catch_signal (sig);
115 }
116 Signal::reset ();
117 ::raise (sig);
118 }
119}
120
122 signal_handler = h;
123#define SIGNAL(SIG) SIG##_handler = signal (SIG, catch_signal);
124 SIGNALS
125#undef SIGNAL
126}
127
128#ifndef WIN32
129
130void Signal::alarm (int seconds) {
131 CADICAL_assert (seconds >= 0);
132 CADICAL_assert (!alarm_set);
133 CADICAL_assert (alarm_time < 0);
134 SIGALRM_handler = signal (SIGALRM, catch_signal);
135 alarm_set = true;
136 alarm_time = absolute_real_time () + seconds;
137 ::alarm (seconds);
138}
139
140#endif
141
142} // namespace CaDiCaL
143
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define SIGNALS
virtual void catch_alarm()
virtual void catch_signal(int sig)=0
static const char * name(int sig)
static void alarm(int seconds)
static void set(Handler *)
static void reset_alarm()
static void reset()
double absolute_real_time()