From 955d5775cb1ec6b62be3dad5075c2e699b276ecc Mon Sep 17 00:00:00 2001 From: Damjan Adamic Date: Fri, 10 Nov 2017 17:23:37 +0100 Subject: [PATCH] =?UTF-8?q?Add=20Lua=20getUsage()=20function=20that=20retu?= =?UTF-8?q?rns=20percent=20of=20already=20used=20up=20i=E2=80=A6=20(#5313)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Lua getUsage() function that returns percent of already used up instructions in current script execution cycle. It can be used to avoid script being killed when doing long lasting tasks (like telemetry logs loading and parsing) * Compilation fixes * Doc fix * Disable Lua script instructions limit in DEBUG mode --- radio/src/lua/api_general.cpp | 16 ++++++++++++++++ radio/src/lua/interface.cpp | 19 +++++++++++++++++-- radio/src/lua/lua_api.h | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index b5162ee9f..aa71bf2ee 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -1171,6 +1171,21 @@ static int luaLoadScript(lua_State * L) } } +/*luadoc +@function getUsage() + +Get percent of already used Lua instructions in current script execution cycle. + +@retval usage (number) a value from 0 to 100 (percent) + +@status current Introduced in 2.2.1 +*/ +static int luaGetUsage(lua_State * L) +{ + lua_pushinteger(L, instructionsPercent); + return 1; +} + const luaL_Reg opentxLib[] = { { "getTime", luaGetTime }, { "getDateTime", luaGetDateTime }, @@ -1193,6 +1208,7 @@ const luaL_Reg opentxLib[] = { { "getRSSI", luaGetRSSI }, { "killEvents", luaKillEvents }, { "loadScript", luaLoadScript }, + { "getUsage", luaGetUsage }, #if LCD_DEPTH > 1 && !defined(COLORLCD) { "GREY", luaGrey }, #endif diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index c013702db..388ac6982 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -44,7 +44,7 @@ ScriptInternalData standaloneScript; uint16_t maxLuaInterval = 0; uint16_t maxLuaDuration = 0; bool luaLcdAllowed; -int instructionsPercent = 0; +uint8_t instructionsPercent = 0; char lua_warning_info[LUA_WARNING_INFO_LEN+1]; struct our_longjmp * global_lj = 0; #if defined(COLORLCD) @@ -65,17 +65,32 @@ int custom_lua_atpanic(lua_State * L) void luaHook(lua_State * L, lua_Debug *ar) { instructionsPercent++; +#if defined(DEBUG) + // Disable Lua script instructions limit in DEBUG mode, + // just report max value reached + static uint16_t max = 0; + if (instructionsPercent > 100) { + if (max + 10 < instructionsPercent) { + max = instructionsPercent; + TRACE("LUA instructionsPercent %u%%", (uint32_t)max); + } + } + else if (instructionsPercent < 10) { + max = 0; + } +#else if (instructionsPercent > 100) { // From now on, as soon as a line is executed, error // keep erroring until you're script reaches the top lua_sethook(L, luaHook, LUA_MASKLINE, 0); luaL_error(L, "CPU limit"); } +#endif } void luaSetInstructionsLimit(lua_State * L, int count) { - instructionsPercent=0; + instructionsPercent = 0; lua_sethook(L, luaHook, LUA_MASKCOUNT, count); } diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index 613ab235e..9fc2a63c0 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -151,6 +151,7 @@ extern struct our_longjmp * global_lj; extern uint16_t maxLuaInterval; extern uint16_t maxLuaDuration; +extern uint8_t instructionsPercent; #if defined(PCBTARANIS) #define IS_MASKABLE(key) ((key) != KEY_EXIT && (key) != KEY_ENTER && ((luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) || (key) != KEY_PAGE))