AP_Scripting: Use dedicated heap

This commit is contained in:
Michael du Breuil 2018-12-08 19:35:08 -07:00 committed by WickedShell
parent 7b259fb09f
commit c191789651
4 changed files with 38 additions and 13 deletions

View File

@ -54,6 +54,15 @@ const AP_Param::GroupInfo AP_Scripting::var_info[] = {
// @User: Advanced // @User: Advanced
AP_GROUPINFO("VM_I_COUNT", 2, AP_Scripting, _script_vm_exec_count, 10000), 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 AP_GROUPEND
}; };
@ -83,7 +92,7 @@ bool AP_Scripting::init(void) {
} }
void AP_Scripting::thread(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) { if (lua == nullptr) {
gcs().send_text(MAV_SEVERITY_CRITICAL, "Unable to allocate scripting memory"); gcs().send_text(MAV_SEVERITY_CRITICAL, "Unable to allocate scripting memory");
return; return;

View File

@ -41,6 +41,7 @@ private:
AP_Int8 _enable; AP_Int8 _enable;
AP_Int32 _script_vm_exec_count; AP_Int32 _script_vm_exec_count;
AP_Int32 _script_heap_size;
static AP_Scripting *_singleton; static AP_Scripting *_singleton;

View File

@ -39,9 +39,9 @@ extern const AP_HAL::HAL& hal;
bool lua_scripts::overtime; bool lua_scripts::overtime;
jmp_buf lua_scripts::panic_jmp; 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) { : _vm_steps(vm_steps) {
scripts = nullptr; _heap = hal.util->allocate_heap_memory(heap_size);
} }
void lua_scripts::hook(lua_State *L, lua_Debug *ar) { 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) { if (new_script == nullptr) {
// No memory, shouldn't happen, we even attempted to do a GC // No memory, shouldn't happen, we even attempted to do a GC
gcs().send_text(MAV_SEVERITY_CRITICAL, "Lua: Insufficent memory loading %s", filename); 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 // 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; 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) { if (filename == nullptr) {
continue; 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 // we have something that looks like a lua file, attempt to load it
script_info * script = load_script(L, filename); script_info * script = load_script(L, filename);
if (script == nullptr) { if (script == nullptr) {
free(filename); hal.util->heap_realloc(_heap, filename, 0);
continue; continue;
} }
reschedule_script(script); 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 // state could be null if we are force killing all scripts
luaL_unref(L, LUA_REGISTRYINDEX, script->lua_ref); luaL_unref(L, LUA_REGISTRYINDEX, script->lua_ref);
} }
free(script->name); hal.util->heap_realloc(_heap, script->name, 0);
free(script); hal.util->heap_realloc(_heap, script, 0);
} }
void lua_scripts::reschedule_script(script_info *script) { void lua_scripts::reschedule_script(script_info *script) {
@ -293,7 +293,19 @@ void lua_scripts::reschedule_script(script_info *script) {
previous->next = 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) { 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 // panic should be hooked first
if (setjmp(panic_jmp)) { if (setjmp(panic_jmp)) {
if (lua_state != nullptr) { if (lua_state != nullptr) {
@ -307,7 +319,7 @@ void lua_scripts::run(void) {
overtime = false; overtime = false;
} }
lua_state = luaL_newstate(); lua_state = lua_newstate(alloc, NULL);
lua_State *L = lua_state; lua_State *L = lua_state;
if (L == nullptr) { if (L == nullptr) {
gcs().send_text(MAV_SEVERITY_CRITICAL, "Lua: Couldn't allocate a lua state"); 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); 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(); const uint32_t loadEnd = AP_HAL::micros();
run_next_script(L); run_next_script(L);
const uint32_t runEnd = AP_HAL::micros(); const uint32_t runEnd = AP_HAL::micros();
const uint32_t endMem = hal.util->available_memory(); 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, startMem - endMem); gcs().send_text(MAV_SEVERITY_DEBUG, "Lua: Time: %d Mem: %d", runEnd - loadEnd, endMem - startMem);
} else { } else {
gcs().send_text(MAV_SEVERITY_DEBUG, "Lua: No scripts to run"); gcs().send_text(MAV_SEVERITY_DEBUG, "Lua: No scripts to run");

View File

@ -23,7 +23,7 @@
class lua_scripts class lua_scripts
{ {
public: public:
lua_scripts(const AP_Int32 &vm_steps); lua_scripts(const AP_Int32 &vm_steps, const AP_Int32 &heap_size);
/* Do not allow copies */ /* Do not allow copies */
lua_scripts(const lua_scripts &other) = delete; lua_scripts(const lua_scripts &other) = delete;
@ -67,4 +67,7 @@ private:
const AP_Int32 & _vm_steps; const AP_Int32 & _vm_steps;
static void *alloc(void *ud, void *ptr, size_t osize, size_t nsize);
static void *_heap;
}; };