#if defined(WIN32) && ! defined(USE_GENERIC)
# define USE_GENERIC
#endif
#ifdef USE_GENERIC
# include <thread>
// using std::thread, std::this_thread
# include <chrono>
// using std::chrono::seconds
# include <csignal>
// using std::raise, SIGABRT, SIGXCPU
#else
# include <sys/time.h>
# include <sys/resource.h>
// using setrlimit
# include <algorithm>
// using std::min
# include <system_error>
// using std::system_error, std::system_category
# include <cerrno>
// using errno
#endif
namespace ext {
#ifdef USE_GENERIC
namespace {
void sleeper_thread(int seconds)
{
std::this_thread::sleep_for(std::chrono::seconds(seconds));
int signal;
# ifdef SIGXCPU
signal = SIGXCPU;
# else
signal = SIGABRT;
# endif
std::raise(signal);
}
}
void limit_time(int seconds)
{
std::thread(sleeper_thread, seconds).detach();
}
#else
void limit_time(int seconds)
{
rlimit limit;
if(getrlimit(RLIMIT_CPU, &limit))
goto err;
if(limit.rlim_max > static_cast<rlim_t>(seconds))
limit.rlim_max = seconds;
limit.rlim_cur = limit.rlim_max;
if(setrlimit(RLIMIT_CPU, &limit))
goto err;
return;
err:
throw std::system_error(errno, std::system_category(), "rlimit");
}
#endif
}
int main()
{
ext::limit_time(10);
int j = 1;
for(unsigned i = 10; i >= 0; --i) // accidental infinite loop
j *= 2;
return j;
}
Comments