lean4-htt/src/include/lean/interrupt.h
2020-05-22 14:17:25 -07:00

106 lines
2.8 KiB
C++

/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#pragma once
#include <utility>
#include <lean/thread.h>
#include <lean/stackinfo.h>
#include <lean/exception.h>
#include <lean/flet.h>
namespace lean {
/** \brief Increment thread local counter for approximating elapsed time. */
void inc_heartbeat();
/** \brief Reset thread local counter for approximating elapsed time. */
void reset_heartbeat();
/* Update the current heartbeat */
class scope_heartbeat : flet<size_t> {
public:
scope_heartbeat(size_t curr);
};
/** \brief Threshold on the number of hearbeats. check_system will throw
an exception if a thread exceeds the limit. The default is unlimited.
The limit is checked in the check_system API.
This is a thread local value. The class lthread uses the
maximum of the parent thread. */
void set_max_heartbeat(size_t max);
void set_max_heartbeat_thousands(unsigned max);
size_t get_max_heartbeat();
/* Update the thread local max heartbeat */
class scope_max_heartbeat : flet<size_t> {
public:
scope_max_heartbeat(size_t max);
};
void check_heartbeat();
struct scoped_interrupt_flag : flet<atomic_bool *> {
scoped_interrupt_flag(atomic_bool *); // NOLINT
};
/**
\brief Throw an interrupted exception if the (interrupt) flag is set.
*/
void check_interrupted();
/**
\brief Check system resources: stack, memory, hearbeat, interrupt flag.
*/
void check_system(char const * component_name);
constexpr unsigned g_small_sleep = 10;
/**
\brief Put the current thread to sleep for \c ms milliseconds.
\remark check_interrupted is invoked every \c step_ms milliseconds;
*/
void sleep_for(unsigned ms, unsigned step_ms = g_small_sleep);
inline void sleep_for(chrono::milliseconds const & ms) { sleep_for(ms.count(), 10); }
/**
\brief Thread that provides a method for setting its interrupt flag.
*/
class interruptible_thread {
public:
template<typename Function>
interruptible_thread(Function && fun):
m_thread([&, fun]() {
save_stack_info(false);
scoped_interrupt_flag scope_int_flag(&m_flag);
fun();
})
{}
/**
\brief Return true iff an interrupt request has been made to the current thread.
*/
bool interrupted() const;
/**
\brief Send a interrupt request to the current thread. Return
true iff the request has been successfully performed.
*/
void request_interrupt();
void join();
private:
atomic_bool m_flag;
lthread m_thread;
};
#if !defined(LEAN_MULTI_THREAD)
inline void check_threadsafe() {
throw exception("Lean was compiled without support for multi-threading");
}
#else
inline void check_threadsafe() {}
#endif
}