feat(library/vm): check heartbeat in function calls
This commit is contained in:
parent
80ac700e36
commit
1306e56381
6 changed files with 33 additions and 13 deletions
|
|
@ -3111,6 +3111,7 @@ void vm_state::run() {
|
|||
}
|
||||
case opcode::InvokeGlobal: {
|
||||
check_interrupted();
|
||||
check_heartbeat();
|
||||
check_memory("vm");
|
||||
/**
|
||||
Instruction: ginvoke fn
|
||||
|
|
@ -3145,6 +3146,7 @@ void vm_state::run() {
|
|||
}
|
||||
case opcode::InvokeBuiltin: {
|
||||
check_interrupted();
|
||||
check_heartbeat();
|
||||
check_memory("vm");
|
||||
/**
|
||||
Instruction: builtin fn
|
||||
|
|
@ -3166,6 +3168,7 @@ void vm_state::run() {
|
|||
}
|
||||
case opcode::InvokeCFun: {
|
||||
check_interrupted();
|
||||
check_heartbeat();
|
||||
check_memory("vm");
|
||||
/**
|
||||
Instruction: cfun fn
|
||||
|
|
|
|||
|
|
@ -55,10 +55,6 @@ char const * memory_exception::what() const noexcept {
|
|||
}
|
||||
|
||||
char const * heartbeat_exception::what() const noexcept {
|
||||
std::string & buffer = get_g_buffer();
|
||||
std::ostringstream s;
|
||||
s << "(deterministic) timeout detected at '" << m_component_name << "' (potential solution: increase timeout threshold)";
|
||||
buffer = s.str();
|
||||
return buffer.c_str();
|
||||
return "(deterministic) timeout";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,11 +87,10 @@ public:
|
|||
};
|
||||
|
||||
class heartbeat_exception : public throwable {
|
||||
std::string m_component_name;
|
||||
public:
|
||||
heartbeat_exception(char const * component_name):m_component_name(component_name) {}
|
||||
heartbeat_exception() {}
|
||||
virtual char const * what() const noexcept;
|
||||
virtual throwable * clone() const { return new heartbeat_exception(m_component_name.c_str()); }
|
||||
virtual throwable * clone() const { return new heartbeat_exception(); }
|
||||
virtual void rethrow() const { throw *this; }
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,10 @@ void set_max_heartbeat_thousands(unsigned max) { g_max_heartbeat = static_cast<s
|
|||
scope_heartbeat::scope_heartbeat(size_t max):flet<size_t>(g_heartbeat, max) {}
|
||||
scope_max_heartbeat::scope_max_heartbeat(size_t max):flet<size_t>(g_max_heartbeat, max) {}
|
||||
|
||||
static void check_heartbeat(char const * component_name) {
|
||||
void check_heartbeat() {
|
||||
inc_heartbeat();
|
||||
if (g_max_heartbeat > 0 && g_heartbeat > g_max_heartbeat)
|
||||
throw heartbeat_exception(component_name);
|
||||
throw heartbeat_exception();
|
||||
}
|
||||
|
||||
MK_THREAD_LOCAL_GET(atomic_bool, get_g_interrupt, false);
|
||||
|
|
@ -54,11 +55,10 @@ void check_interrupted() {
|
|||
}
|
||||
|
||||
void check_system(char const * component_name) {
|
||||
inc_heartbeat();
|
||||
check_stack(component_name);
|
||||
check_memory(component_name);
|
||||
check_interrupted();
|
||||
check_heartbeat(component_name);
|
||||
check_heartbeat();
|
||||
}
|
||||
|
||||
void sleep_for(unsigned ms, unsigned step_ms) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public:
|
|||
scope_max_heartbeat(size_t max);
|
||||
};
|
||||
|
||||
void init_thread_max_heartbeat();
|
||||
void check_heartbeat();
|
||||
|
||||
atomic_bool * get_interrupt_flag();
|
||||
|
||||
|
|
|
|||
22
tests/lean/run/try_for1.lean
Normal file
22
tests/lean/run/try_for1.lean
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
meta def f : nat → nat
|
||||
| n := f (n + 1)
|
||||
|
||||
vm_eval try_for 100 (f 10)
|
||||
|
||||
vm_eval try_for 1000 (f 10)
|
||||
|
||||
meta def mk : nat → list nat
|
||||
| 0 := []
|
||||
| (n+1) := n :: mk n
|
||||
|
||||
example : true :=
|
||||
begin
|
||||
tactic.fail_if_success (guard(to_bool (try_for 1 ((mk 1000)^.length) = some 1000))),
|
||||
constructor
|
||||
end
|
||||
|
||||
example : true :=
|
||||
begin
|
||||
guard (try_for 100 ((mk 1000)^.length) = some 1000),
|
||||
constructor
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue