be506a51882d6f80655857bca1cb2398eb0ce312
1 /********************* */
2 /*! \file time_limit.cpp
4 ** Top contributors (to current version):
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
8 ** in the top-level source directory and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
12 ** \brief Implementation of time limits.
14 ** Implementation of time limits that are imposed by the --tlimit option.
17 #include "time_limit.h"
19 #if defined(__MINGW32__) || defined(__MINGW64__)
29 #include "signal_handlers.h"
34 #if defined(__MINGW32__) || defined(__MINGW64__)
35 void CALLBACK
win_timeout_handler(LPVOID lpArg
,
36 DWORD dwTimerLowValue
,
37 DWORD dwTimerHighValue
)
39 signal_handlers::timeout_handler();
42 void posix_timeout_handler(int sig
, siginfo_t
* info
, void*)
44 signal_handlers::timeout_handler();
48 void install_time_limit(const Options
& opts
)
50 unsigned long ms
= opts
.getCumulativeTimeLimit();
51 // Skip if no time limit shall be set.
54 #if defined(__MINGW32__) || defined(__MINGW64__)
55 HANDLE hTimer
= CreateWaitableTimer(nullptr, true, TEXT("CVC4::Timeout"));
56 if (hTimer
== nullptr)
58 throw Exception(std::string("CreateWaitableTimer() failure: ")
59 + std::to_string(GetLastError()));
61 LARGE_INTEGER liDueTime
;
62 liDueTime
.LowPart
= (DWORD
)(ms
& 0xFFFFFFFF);
63 liDueTime
.HighPart
= 0;
64 if (!SetWaitableTimer(
65 hTimer
, &liDueTime
, 0, win_timeout_handler
, nullptr, false))
67 throw Exception(std::string("SetWaitableTimer() failure: ")
68 + std::to_string(GetLastError()));
71 // Install a signal handler for SIGALRM
72 struct sigaction sact
;
73 sact
.sa_sigaction
= posix_timeout_handler
;
74 sact
.sa_flags
= SA_SIGINFO
;
75 sigemptyset(&sact
.sa_mask
);
76 if (sigaction(SIGALRM
, &sact
, NULL
))
78 throw Exception(std::string("sigaction(SIGALRM) failure: ")
82 // Check https://linux.die.net/man/2/setitimer
83 // Then time is up, the kernel will send a SIGALRM
84 struct itimerval timerspec
;
85 timerspec
.it_value
.tv_sec
= ms
/ 1000;
86 timerspec
.it_value
.tv_usec
= (ms
% 1000) * 1000;
87 timerspec
.it_interval
.tv_sec
= 0;
88 timerspec
.it_interval
.tv_usec
= 0;
89 // Argument 1: which timer to set, we want the real time
90 // Argument 2: timer configuration, relative to current time
91 // Argument 3: old timer configuration, we don't want to know
92 if (setitimer(ITIMER_REAL
, &timerspec
, nullptr))
94 throw Exception(std::string("timer_settime() failure: ") + strerror(errno
));