diff --git a/libraries/AP_Scripting/AP_Scripting.cpp b/libraries/AP_Scripting/AP_Scripting.cpp index c3571612a2..3c19f8e16f 100644 --- a/libraries/AP_Scripting/AP_Scripting.cpp +++ b/libraries/AP_Scripting/AP_Scripting.cpp @@ -54,6 +54,15 @@ const AP_Param::GroupInfo AP_Scripting::var_info[] = { // @User: Advanced AP_GROUPINFO("VM_I_COUNT", 2, AP_Scripting, _script_vm_exec_count, 10000), + // @Param: HEAP_SIZE + // @DisplayName: Scripting Heap Size + // @Description: Amount of memory available for scripting + // @Range: 1024 1048576 + // @Increment: 1024 + // @User: Advanced + // @RebootRequired: True + AP_GROUPINFO("HEAP_SIZE", 3, AP_Scripting, _script_heap_size, 32*1024), + AP_GROUPEND }; @@ -83,7 +92,7 @@ bool AP_Scripting::init(void) { } void AP_Scripting::thread(void) { - lua_scripts *lua = new lua_scripts(_script_vm_exec_count); + lua_scripts *lua = new lua_scripts(_script_vm_exec_count, _script_heap_size); if (lua == nullptr) { gcs().send_text(MAV_SEVERITY_CRITICAL, "Unable to allocate scripting memory"); return; diff --git a/libraries/AP_Scripting/AP_Scripting.h b/libraries/AP_Scripting/AP_Scripting.h index 59463d0a5e..cbeeb0a754 100644 --- a/libraries/AP_Scripting/AP_Scripting.h +++ b/libraries/AP_Scripting/AP_Scripting.h @@ -41,6 +41,7 @@ private: AP_Int8 _enable; AP_Int32 _script_vm_exec_count; + AP_Int32 _script_heap_size; static AP_Scripting *_singleton; diff --git a/libraries/AP_Scripting/lua_scripts.cpp b/libraries/AP_Scripting/lua_scripts.cpp index 73afe9380c..9b77bbafc8 100644 --- a/libraries/AP_Scripting/lua_scripts.cpp +++ b/libraries/AP_Scripting/lua_scripts.cpp @@ -39,9 +39,9 @@ extern const AP_HAL::HAL& hal; bool lua_scripts::overtime; jmp_buf lua_scripts::panic_jmp; -lua_scripts::lua_scripts(const AP_Int32 &vm_steps) +lua_scripts::lua_scripts(const AP_Int32 &vm_steps, const AP_Int32 &heap_size) : _vm_steps(vm_steps) { - scripts = nullptr; + _heap = hal.util->allocate_heap_memory(heap_size); } void lua_scripts::hook(lua_State *L, lua_Debug *ar) { @@ -80,7 +80,7 @@ lua_scripts::script_info *lua_scripts::load_script(lua_State *L, char *filename) } } - script_info *new_script = (script_info *)malloc(sizeof(script_info)); + script_info *new_script = (script_info *)hal.util->heap_realloc(_heap, nullptr, sizeof(script_info)); if (new_script == nullptr) { // No memory, shouldn't happen, we even attempted to do a GC gcs().send_text(MAV_SEVERITY_CRITICAL, "Lua: Insufficent memory loading %s", filename); @@ -132,7 +132,7 @@ void lua_scripts::load_all_scripts_in_dir(lua_State *L, const char *dirname) { // FIXME: because chunk name fetching is not working we are allocating and storing an extra string we shouldn't need to size_t size = strlen(dirname) + strlen(de->d_name) + 2; - char * filename = (char *)malloc(size); + char * filename = (char *) hal.util->heap_realloc(_heap, nullptr, size); if (filename == nullptr) { continue; } @@ -141,7 +141,7 @@ void lua_scripts::load_all_scripts_in_dir(lua_State *L, const char *dirname) { // we have something that looks like a lua file, attempt to load it script_info * script = load_script(L, filename); if (script == nullptr) { - free(filename); + hal.util->heap_realloc(_heap, filename, 0); continue; } reschedule_script(script); @@ -254,8 +254,8 @@ void lua_scripts::remove_script(lua_State *L, script_info *script) { // state could be null if we are force killing all scripts luaL_unref(L, LUA_REGISTRYINDEX, script->lua_ref); } - free(script->name); - free(script); + hal.util->heap_realloc(_heap, script->name, 0); + hal.util->heap_realloc(_heap, script, 0); } void lua_scripts::reschedule_script(script_info *script) { @@ -293,7 +293,19 @@ void lua_scripts::reschedule_script(script_info *script) { previous->next = script; } +void *lua_scripts::_heap; + +void *lua_scripts::alloc(void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; (void)osize; /* not used */ + return hal.util->heap_realloc(_heap, ptr, nsize); +} + void lua_scripts::run(void) { + if (_heap == nullptr) { + gcs().send_text(MAV_SEVERITY_INFO, "Lua: Unable to allocate a heap"); + return; + } + // panic should be hooked first if (setjmp(panic_jmp)) { if (lua_state != nullptr) { @@ -307,7 +319,7 @@ void lua_scripts::run(void) { overtime = false; } - lua_state = luaL_newstate(); + lua_state = lua_newstate(alloc, NULL); lua_State *L = lua_state; if (L == nullptr) { gcs().send_text(MAV_SEVERITY_CRITICAL, "Lua: Couldn't allocate a lua state"); @@ -361,14 +373,14 @@ void lua_scripts::run(void) { gcs().send_text(MAV_SEVERITY_DEBUG, "Lua: Running %s", scripts->name); - const uint32_t startMem = hal.util->available_memory(); + const uint32_t startMem = lua_gc(L, LUA_GCCOUNT, 0) * 1024 + lua_gc(L, LUA_GCCOUNTB, 0); const uint32_t loadEnd = AP_HAL::micros(); run_next_script(L); const uint32_t runEnd = AP_HAL::micros(); - const uint32_t endMem = hal.util->available_memory(); - gcs().send_text(MAV_SEVERITY_DEBUG, "Lua: Time: %d Mem: %d", runEnd - loadEnd, startMem - endMem); + const uint32_t endMem = lua_gc(L, LUA_GCCOUNT, 0) * 1024 + lua_gc(L, LUA_GCCOUNTB, 0); + gcs().send_text(MAV_SEVERITY_DEBUG, "Lua: Time: %d Mem: %d", runEnd - loadEnd, endMem - startMem); } else { gcs().send_text(MAV_SEVERITY_DEBUG, "Lua: No scripts to run"); diff --git a/libraries/AP_Scripting/lua_scripts.h b/libraries/AP_Scripting/lua_scripts.h index a4d65b87c4..7241115dc4 100644 --- a/libraries/AP_Scripting/lua_scripts.h +++ b/libraries/AP_Scripting/lua_scripts.h @@ -23,7 +23,7 @@ class lua_scripts { public: - lua_scripts(const AP_Int32 &vm_steps); + lua_scripts(const AP_Int32 &vm_steps, const AP_Int32 &heap_size); /* Do not allow copies */ lua_scripts(const lua_scripts &other) = delete; @@ -67,4 +67,7 @@ private: const AP_Int32 & _vm_steps; + static void *alloc(void *ud, void *ptr, size_t osize, size_t nsize); + + static void *_heap; };