refactor watchdog

This commit is contained in:
blueloveTH 2025-05-22 17:17:06 +08:00
parent 340309b5d4
commit 4438b54846
8 changed files with 19 additions and 37 deletions

View File

@ -5,10 +5,9 @@
#include "pocketpy/pocketpy.h" #include "pocketpy/pocketpy.h"
#include "pocketpy/interpreter/heap.h" #include "pocketpy/interpreter/heap.h"
#include "pocketpy/interpreter/frame.h" #include "pocketpy/interpreter/frame.h"
#include "pocketpy/interpreter/modules.h"
#include "pocketpy/interpreter/typeinfo.h" #include "pocketpy/interpreter/typeinfo.h"
#include "pocketpy/interpreter/name.h" #include "pocketpy/interpreter/name.h"
#include "pocketpy/interpreter/types.h" #include <time.h>
// TODO: // TODO:
// 1. __eq__ and __ne__ fallbacks // 1. __eq__ and __ne__ fallbacks
@ -24,8 +23,7 @@ typedef struct TraceInfo {
} TraceInfo; } TraceInfo;
typedef struct WatchdogInfo { typedef struct WatchdogInfo {
py_i64 timeout; clock_t max_reset_time;
py_i64 last_reset_time;
} WatchdogInfo; } WatchdogInfo;
typedef struct VM { typedef struct VM {

View File

@ -111,14 +111,12 @@ PK_API void py_sys_settrace(py_TraceFunc func);
/// Setup the callbacks for the current VM. /// Setup the callbacks for the current VM.
PK_API py_Callbacks* py_callbacks(); PK_API py_Callbacks* py_callbacks();
/// Begin the watchdog with a timeout in milliseconds. /// Begin the watchdog with `timeout` in milliseconds.
/// `PK_ENABLE_WATCHDOG` must be defined to `1` to use this feature. /// `PK_ENABLE_WATCHDOG` must be defined to `1` to use this feature.
/// You need to call `py_watchdog_reset()` periodically to keep the watchdog alive. /// You need to call `py_watchdog_end()` later.
/// If the timeout is reached, `TimeoutError` will be raised. /// If `timeout` is reached, `TimeoutError` will be raised.
PK_API void py_watchdog_begin(py_i64 timeout); PK_API void py_watchdog_begin(py_i64 timeout);
/// Reset the watchdog. /// Reset the watchdog.
PK_API void py_watchdog_reset();
/// End the watchdog.
PK_API void py_watchdog_end(); PK_API void py_watchdog_end();
/// Get the current source location of the frame. /// Get the current source location of the frame.

View File

@ -27,15 +27,13 @@ def currentvm() -> int:
def watchdog_begin(timeout: int): def watchdog_begin(timeout: int):
""" """
Begin the watchdog with a timeout in milliseconds. Begin the watchdog with `timeout` in milliseconds.
`PK_ENABLE_WATCHDOG` must be defined to `1` to use this feature. `PK_ENABLE_WATCHDOG` must be defined to `1` to use this feature.
You need to call `watchdog_reset()` periodically to keep the watchdog alive. You need to call `watchdog_end()` later.
If the timeout is reached, `TimeoutError` will be raised. If `timeout` is reached, `TimeoutError` will be raised.
""" """
def watchdog_reset():
"""Reset the watchdog."""
def watchdog_end(): def watchdog_end():
"""End the watchdog.""" """Reset the watchdog."""
class ComputeThread: class ComputeThread:

View File

@ -109,11 +109,10 @@ FrameResult VM__run_top_frame(VM* self) {
} }
#if PK_ENABLE_WATCHDOG #if PK_ENABLE_WATCHDOG
if(self->watchdog_info.timeout > 0){ if(self->watchdog_info.max_reset_time > 0){
py_i64 now = clock() / (CLOCKS_PER_SEC / 1000); clock_t now = clock();
py_i64 delta = now - self->watchdog_info.last_reset_time; if(now > self->watchdog_info.max_reset_time) {
if(delta > self->watchdog_info.timeout) { self->watchdog_info.max_reset_time = 0;
self->watchdog_info.last_reset_time = now;
TimeoutError("watchdog timeout"); TimeoutError("watchdog timeout");
goto __ERROR; goto __ERROR;
} }

View File

@ -6,6 +6,7 @@
#include "pocketpy/interpreter/modules.h" #include "pocketpy/interpreter/modules.h"
#include "pocketpy/interpreter/typeinfo.h" #include "pocketpy/interpreter/typeinfo.h"
#include "pocketpy/objects/base.h" #include "pocketpy/objects/base.h"
#include "pocketpy/interpreter/types.h"
#include "pocketpy/common/_generated.h" #include "pocketpy/common/_generated.h"
#include "pocketpy/pocketpy.h" #include "pocketpy/pocketpy.h"
#include <stdbool.h> #include <stdbool.h>

View File

@ -7,6 +7,7 @@
#include "pocketpy/interpreter/vm.h" #include "pocketpy/interpreter/vm.h"
#include "pocketpy/common/threads.h" #include "pocketpy/common/threads.h"
#include <time.h>
#define DEF_TVALUE_METHODS(T, Field) \ #define DEF_TVALUE_METHODS(T, Field) \
static bool TValue_##T##__new__(int argc, py_Ref argv) { \ static bool TValue_##T##__new__(int argc, py_Ref argv) { \
@ -81,18 +82,12 @@ static bool pkpy_currentvm(int argc, py_Ref argv) {
#if PK_ENABLE_WATCHDOG #if PK_ENABLE_WATCHDOG
void py_watchdog_begin(py_i64 timeout) { void py_watchdog_begin(py_i64 timeout) {
WatchdogInfo* info = &pk_current_vm->watchdog_info; WatchdogInfo* info = &pk_current_vm->watchdog_info;
info->timeout = timeout; info->max_reset_time = clock() + (timeout * (CLOCKS_PER_SEC / 1000));
py_watchdog_reset();
}
void py_watchdog_reset() {
WatchdogInfo* info = &pk_current_vm->watchdog_info;
info->last_reset_time = clock() / (CLOCKS_PER_SEC / 1000);
} }
void py_watchdog_end() { void py_watchdog_end() {
WatchdogInfo* info = &pk_current_vm->watchdog_info; WatchdogInfo* info = &pk_current_vm->watchdog_info;
info->timeout = 0; info->max_reset_time = 0;
} }
static bool pkpy_watchdog_begin(int argc, py_Ref argv) { static bool pkpy_watchdog_begin(int argc, py_Ref argv) {
@ -103,13 +98,6 @@ static bool pkpy_watchdog_begin(int argc, py_Ref argv) {
return true; return true;
} }
static bool pkpy_watchdog_reset(int argc, py_Ref argv) {
PY_CHECK_ARGC(0);
py_watchdog_reset();
py_newnone(py_retval());
return true;
}
static bool pkpy_watchdog_end(int argc, py_Ref argv) { static bool pkpy_watchdog_end(int argc, py_Ref argv) {
PY_CHECK_ARGC(0); PY_CHECK_ARGC(0);
py_watchdog_end(); py_watchdog_end();
@ -508,7 +496,6 @@ void pk__add_module_pkpy() {
#if PK_ENABLE_WATCHDOG #if PK_ENABLE_WATCHDOG
py_bindfunc(mod, "watchdog_begin", pkpy_watchdog_begin); py_bindfunc(mod, "watchdog_begin", pkpy_watchdog_begin);
py_bindfunc(mod, "watchdog_reset", pkpy_watchdog_reset);
py_bindfunc(mod, "watchdog_end", pkpy_watchdog_end); py_bindfunc(mod, "watchdog_end", pkpy_watchdog_end);
#endif #endif

View File

@ -2,7 +2,7 @@
#include "pocketpy/common/utils.h" #include "pocketpy/common/utils.h"
#include "pocketpy/common/sstream.h" #include "pocketpy/common/sstream.h"
#include "pocketpy/objects/object.h" #include "pocketpy/interpreter/types.h"
#include "pocketpy/interpreter/vm.h" #include "pocketpy/interpreter/vm.h"
static uint32_t Dict__next_cap(uint32_t cap) { static uint32_t Dict__next_cap(uint32_t cap) {

View File

@ -2,6 +2,7 @@
#include "pocketpy/common/utils.h" #include "pocketpy/common/utils.h"
#include "pocketpy/interpreter/vm.h" #include "pocketpy/interpreter/vm.h"
#include "pocketpy/interpreter/types.h"
#include "pocketpy/common/sstream.h" #include "pocketpy/common/sstream.h"
void py_newlist(py_OutRef out) { void py_newlist(py_OutRef out) {