mirror of
https://github.com/opentx/opentx.git
synced 2025-07-14 20:10:08 +03:00
Fixes #1791: Port Lua Bin Allocator to next:
* Bin Allocator * Lua memory allocaton fixes * Simulator memory leak fixes
This commit is contained in:
parent
56a4cf5d26
commit
c89381bae5
19 changed files with 294 additions and 13 deletions
|
@ -3073,6 +3073,11 @@ FRESULT f_opendir (
|
|||
}
|
||||
|
||||
|
||||
FRESULT f_closedir (DIR * rep)
|
||||
{
|
||||
//apparently nothing to do in FatFS
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -209,6 +209,7 @@ FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a
|
|||
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR* dj, const TCHAR* path); /* Open an existing directory */
|
||||
FRESULT f_closedir (DIR * rep);
|
||||
FRESULT f_readdir (DIR* dj, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
|
||||
|
|
|
@ -297,6 +297,13 @@ CHANNELS_MONITOR_INV_HIDE = NO
|
|||
# Values = NO, YES
|
||||
NANO = NO
|
||||
|
||||
# Use custom bin based allocator for Lua
|
||||
# Values = NO, YES
|
||||
# YES - use our bin based allocator
|
||||
# NO - use default Lua allocator
|
||||
USE_BIN_ALLOCATOR = NO
|
||||
|
||||
|
||||
# Enable trace of events into Trace Buffer for debugging purposes
|
||||
# Activating any of these options also activates DEBUG and DEBUG_TRACE_BUFFER
|
||||
# Values = NO, YES
|
||||
|
@ -776,6 +783,10 @@ ifeq ($(PCB), TARANIS)
|
|||
lua/src/lbaselib.c lua/src/linit.c lua/src/lmathlib.c lua/src/lbitlib.c lua/src/loadlib.c lua/src/lauxlib.c lua/src/ltablib.c lua/src/lcorolib.c
|
||||
SRC += $(LUASRC)
|
||||
LUADEP = lua_exports.cpp
|
||||
ifeq ($(USE_BIN_ALLOCATOR), YES)
|
||||
CPPDEFS += -DUSE_BIN_ALLOCATOR
|
||||
CPPSRC += bin_allocator.cpp
|
||||
endif
|
||||
endif
|
||||
ifeq ($(SDCARD), YES)
|
||||
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/taranis/diskio.cpp
|
||||
|
|
|
@ -274,6 +274,7 @@ void referenceSystemAudioFiles()
|
|||
}
|
||||
}
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
|
||||
sdAvailableSystemAudioFiles = availableAudioFiles;
|
||||
|
@ -395,6 +396,7 @@ void referenceModelAudioFiles()
|
|||
}
|
||||
}
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
111
radio/src/bin_allocator.cpp
Normal file
111
radio/src/bin_allocator.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "opentx.h"
|
||||
#include "bin_allocator.h"
|
||||
|
||||
|
||||
BinAllocator_slots1 slots1;
|
||||
BinAllocator_slots2 slots2;
|
||||
|
||||
#if defined(DEBUG)
|
||||
int SimulateMallocFailure = 0; //set this to simulate allocation failure
|
||||
#endif
|
||||
|
||||
bool bin_free(void * ptr)
|
||||
{
|
||||
//return TRUE if ours
|
||||
return slots1.free(ptr) || slots2.free(ptr);
|
||||
}
|
||||
|
||||
void * bin_malloc(size_t size) {
|
||||
//try to allocate from our space
|
||||
void * res = slots1.malloc(size);
|
||||
return res ? res : slots2.malloc(size);
|
||||
}
|
||||
|
||||
void * bin_realloc(void * ptr, size_t size)
|
||||
{
|
||||
if (ptr == 0) {
|
||||
//no previous data, try our malloc
|
||||
return bin_malloc(size);
|
||||
}
|
||||
else {
|
||||
if (! (slots1.is_member(ptr) || slots2.is_member(ptr)) ) {
|
||||
// not our data, leave it to libc realloc
|
||||
return 0;
|
||||
}
|
||||
|
||||
//we have existing data
|
||||
// if it fits in current slot, return it
|
||||
// TODO if new size is smaller, try to relocate in smaller slot
|
||||
if ( slots1.can_fit(ptr, size) ) {
|
||||
// TRACE("OUR realloc %p[%lu] fits in slot1", ptr, size); FLUSH();
|
||||
return ptr;
|
||||
}
|
||||
if ( slots2.can_fit(ptr, size) ) {
|
||||
// TRACE("OUR realloc %p[%lu] fits in slot2", ptr, size); FLUSH();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//we need a bigger slot
|
||||
void * res = bin_malloc(size);
|
||||
if (res == 0) {
|
||||
// we don't have the space, use libc malloc
|
||||
// TRACE("bin_malloc [%lu] FAILURE", size); FLUSH();
|
||||
res = malloc(size);
|
||||
if (res == 0) {
|
||||
TRACE("libc malloc [%lu] FAILURE", size); FLUSH();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//copy data
|
||||
memcpy(res, ptr, slots1.size(ptr) + slots2.size(ptr));
|
||||
bin_free(ptr);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *bin_l_alloc (void *ud, void *ptr, size_t osize, size_t nsize)
|
||||
{
|
||||
(void)ud; (void)osize; /* not used */
|
||||
if (nsize == 0) {
|
||||
if (ptr) { // avoid a bunch of NULL pointer free calls
|
||||
if (!bin_free(ptr)) {
|
||||
// not our range, use libc allocator
|
||||
// TRACE("libc free %p", ptr); FLUSH();
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
#if defined(DEBUG)
|
||||
if (SimulateMallocFailure < 0 ) {
|
||||
//delayed failure
|
||||
if (++SimulateMallocFailure == 0) {
|
||||
SimulateMallocFailure = 1;
|
||||
}
|
||||
}
|
||||
if ( SimulateMallocFailure > 0) {
|
||||
// simulate one malloc failure
|
||||
TRACE("bin_l_alloc(): simulating malloc failure at %p[%lu]", ptr, nsize); FLUSH();
|
||||
return 0;
|
||||
}
|
||||
#endif // #if defined(DEBUG)
|
||||
// try our allocator, if it fails use libc allocator
|
||||
void * res = bin_realloc(ptr, nsize);
|
||||
if (res && ptr) {
|
||||
// TRACE("OUR realloc %p[%lu] -> %p[%lu]", ptr, osize, res, nsize); FLUSH();
|
||||
}
|
||||
if (res == 0) {
|
||||
res = realloc(ptr, nsize);
|
||||
// TRACE("libc realloc %p[%lu] -> %p[%lu]", ptr, osize, res, nsize); FLUSH();
|
||||
// if (res == 0 ){
|
||||
// TRACE("realloc FAILURE %lu", nsize);
|
||||
// dumpFreeMemory();
|
||||
// }
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
78
radio/src/bin_allocator.h
Normal file
78
radio/src/bin_allocator.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
#ifndef binallocator_h
|
||||
#define binallocator_h
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
template <int SIZE_SLOT, int NUM_BINS> class BinAllocator {
|
||||
private:
|
||||
PACK(struct Bin {
|
||||
char data[SIZE_SLOT];
|
||||
bool Used;
|
||||
});
|
||||
struct Bin Bins[NUM_BINS];
|
||||
int NoUsedBins;
|
||||
public:
|
||||
BinAllocator() : NoUsedBins(0) {
|
||||
memclear(Bins, sizeof(Bins));
|
||||
}
|
||||
bool free(void * ptr) {
|
||||
for (size_t n = 0; n < NUM_BINS; ++n) {
|
||||
if (ptr == Bins[n].data) {
|
||||
Bins[n].Used = false;
|
||||
--NoUsedBins;
|
||||
// TRACE("\tBinAllocator<%d> free %lu ------", SIZE_SLOT, n); FLUSH();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool is_member(void * ptr) {
|
||||
return (ptr >= Bins[0].data && ptr <= Bins[NUM_BINS-1].data);
|
||||
}
|
||||
void * malloc(size_t size) {
|
||||
if (size > SIZE_SLOT) {
|
||||
// TRACE("BinAllocator<%d> malloc [%lu] size > SIZE_SLOT", SIZE_SLOT, size); FLUSH();
|
||||
return 0;
|
||||
}
|
||||
if (NoUsedBins >= NUM_BINS) {
|
||||
// TRACE("BinAllocator<%d> malloc [%lu] no free slots", SIZE_SLOT, size); FLUSH();
|
||||
return 0;
|
||||
}
|
||||
for (size_t n = 0; n < NUM_BINS; ++n) {
|
||||
if (!Bins[n].Used) {
|
||||
Bins[n].Used = true;
|
||||
++NoUsedBins;
|
||||
// TRACE("\tBinAllocator<%d> malloc %lu[%lu]", SIZE_SLOT, n, size); FLUSH();
|
||||
return Bins[n].data;
|
||||
}
|
||||
}
|
||||
// TRACE("BinAllocator<%d> malloc [%lu] no free slots", SIZE_SLOT , size); FLUSH();
|
||||
return 0;
|
||||
}
|
||||
size_t size(void * ptr) {
|
||||
return is_member(ptr) ? SIZE_SLOT : 0;
|
||||
}
|
||||
bool can_fit(void * ptr, size_t size) {
|
||||
return is_member(ptr) && size <= SIZE_SLOT; //todo is_member check is redundant
|
||||
}
|
||||
unsigned int capacity() { return NUM_BINS; }
|
||||
unsigned int size() { return NoUsedBins; }
|
||||
};
|
||||
|
||||
#if defined(SIMU)
|
||||
typedef BinAllocator<39,300> BinAllocator_slots1;
|
||||
typedef BinAllocator<79,100> BinAllocator_slots2;
|
||||
#else
|
||||
typedef BinAllocator<29,200> BinAllocator_slots1;
|
||||
typedef BinAllocator<91,50> BinAllocator_slots2;
|
||||
#endif
|
||||
|
||||
#if defined(USE_BIN_ALLOCATOR)
|
||||
extern BinAllocator_slots1 slots1;
|
||||
extern BinAllocator_slots2 slots2;
|
||||
|
||||
// wrapper for our BinAllocator for Lua
|
||||
void *bin_l_alloc (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
#endif //#if defined(USE_BIN_ALLOCATOR)
|
||||
|
||||
#endif //binallocator_h
|
|
@ -137,6 +137,13 @@ static void dispw_256( register uint32_t address, register uint32_t lines )
|
|||
}
|
||||
}
|
||||
|
||||
extern Fifo<512> uart3TxFifo;
|
||||
|
||||
void debugFlush()
|
||||
{
|
||||
uart3TxFifo.flush();
|
||||
}
|
||||
|
||||
void debugTask(void* pdata)
|
||||
{
|
||||
uint8_t rxchar ;
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
#define TRACE_WARNING(...) do { printf("-W- " __VA_ARGS__); fflush(stdout); } while(0)
|
||||
#define TRACE_WARNING_WP(...) do { printf(__VA_ARGS__); fflush(stdout); } while(0)
|
||||
#define TRACE_ERROR(...) do { printf("-E- " __VA_ARGS__); fflush(stdout); } while(0)
|
||||
#define FLUSH()
|
||||
|
||||
inline void dump(void * data, unsigned int size)
|
||||
{
|
||||
unsigned char *uchar_data = (unsigned char *)data;
|
||||
|
@ -78,6 +80,7 @@ extern "C" {
|
|||
|
||||
void debugPuts(const char *string, ...);
|
||||
void dump(unsigned char *data, unsigned int size);
|
||||
void debugFlush();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -92,7 +95,7 @@ void dump(unsigned char *data, unsigned int size);
|
|||
#define TRACE_WARNING(...) debugPuts("-W- " __VA_ARGS__)
|
||||
#define TRACE_WARNING_WP(...) debugPuts(__VA_ARGS__)
|
||||
#define TRACE_ERROR(...) debugPuts("-E- " __VA_ARGS__)
|
||||
|
||||
#define FLUSH() debugFlush();
|
||||
void debugTask(void* pdata);
|
||||
|
||||
#else
|
||||
|
@ -106,6 +109,7 @@ void debugTask(void* pdata);
|
|||
#define TRACE_WARNING(...) { }
|
||||
#define TRACE_WARNING_WP(...) { }
|
||||
#define TRACE_ERROR(...) { }
|
||||
#define FLUSH()
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -682,6 +682,9 @@ const pm_char * eeBackupModel(uint8_t i_fileSrc)
|
|||
if (result != FR_OK)
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
else {
|
||||
f_closedir(&archiveFolder);
|
||||
}
|
||||
|
||||
buf[sizeof(MODELS_PATH)-1] = '/';
|
||||
strcpy(strcat_modelname(&buf[sizeof(MODELS_PATH)], i_fileSrc), STR_MODELS_EXT);
|
||||
|
|
|
@ -47,10 +47,6 @@ class Fifo
|
|||
{
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
return (ridx == widx);
|
||||
}
|
||||
|
||||
void push(uint8_t byte) {
|
||||
uint32_t next = (widx+1) & (N-1);
|
||||
if (next != ridx) {
|
||||
|
@ -69,6 +65,12 @@ class Fifo
|
|||
return true;
|
||||
}
|
||||
}
|
||||
bool empty() {
|
||||
return (ridx == widx);
|
||||
}
|
||||
void flush() {
|
||||
while (!empty()) {};
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t fifo[N];
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <stdio.h>
|
||||
#include "opentx.h"
|
||||
#include "stamp-opentx.h"
|
||||
#include "bin_allocator.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
extern "C" {
|
||||
|
@ -1566,7 +1567,11 @@ void luaInit()
|
|||
{
|
||||
luaClose();
|
||||
if (luaState != INTERPRETER_PANIC) {
|
||||
L = luaL_newstate();
|
||||
#if defined(USE_BIN_ALLOCATOR)
|
||||
L = lua_newstate(bin_l_alloc, NULL); //we use our own allocator!
|
||||
#else
|
||||
L = lua_newstate(l_alloc, NULL); //we use Lua default allocator
|
||||
#endif
|
||||
if (L) {
|
||||
// install our panic handler
|
||||
lua_atpanic(L, &custom_lua_atpanic);
|
||||
|
|
|
@ -954,10 +954,13 @@ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
|
|||
}
|
||||
|
||||
|
||||
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
|
||||
void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
|
||||
(void)ud; (void)osize; /* not used */
|
||||
if (nsize == 0) {
|
||||
if (ptr) { // avoid a bunch of NULL pointer free calls
|
||||
// TRACE("free %p", ptr); FLUSH();
|
||||
free(ptr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -93,6 +93,8 @@ LUALIB_API int (luaL_len) (lua_State *L, int idx);
|
|||
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
|
||||
const char *r);
|
||||
|
||||
LUALIB_API void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
|
||||
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
|
||||
|
||||
LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
|
||||
|
|
|
@ -205,6 +205,12 @@ static int stackinuse (lua_State *L) {
|
|||
void luaD_shrinkstack (lua_State *L) {
|
||||
int inuse = stackinuse(L);
|
||||
int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
|
||||
if ((L->stacksize - goodsize) < 40) {
|
||||
//skip shrink
|
||||
// TRACE("luaD_shrinkstack(skip): L->stacksize: %d, goodsize: %d", L->stacksize, goodsize);
|
||||
return;
|
||||
}
|
||||
// TRACE("luaD_shrinkstack(): L->stacksize: %d, goodsize: %d", L->stacksize, goodsize);
|
||||
if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
|
||||
if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */
|
||||
goodsize >= L->stacksize) /* would grow instead of shrink? */
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "luaconf.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define LUA_VERSION_MAJOR "5"
|
||||
#define LUA_VERSION_MINOR "2"
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#if defined(SDCARD)
|
||||
#define USE_FATFS
|
||||
#endif
|
||||
|
||||
/*
|
||||
** ==================================================================
|
||||
|
|
|
@ -55,6 +55,7 @@ class Open9xSim: public FXMainWindow
|
|||
public:
|
||||
Open9xSim(){};
|
||||
Open9xSim(FXApp* a);
|
||||
~Open9xSim();
|
||||
long onKeypress(FXObject*,FXSelector,void*);
|
||||
long onTimeout(FXObject*,FXSelector,void*);
|
||||
void makeSnapshot(const FXDrawable* drawable);
|
||||
|
@ -67,7 +68,7 @@ class Open9xSim: public FXMainWindow
|
|||
bool firstTime;
|
||||
|
||||
public:
|
||||
FXSlider *sliders[8];
|
||||
FXSlider *sliders[NUM_STICKS];
|
||||
FXKnob *knobs[NUM_POTS];
|
||||
};
|
||||
|
||||
|
@ -127,6 +128,24 @@ Open9xSim::Open9xSim(FXApp* a):
|
|||
getApp()->addTimeout(this,2,100);
|
||||
}
|
||||
|
||||
Open9xSim::~Open9xSim()
|
||||
{
|
||||
StopMainThread();
|
||||
StopEepromThread();
|
||||
|
||||
delete bmp;
|
||||
delete sliders[0];
|
||||
delete sliders[1];
|
||||
delete sliders[2];
|
||||
delete sliders[3];
|
||||
|
||||
for(int i=0; i<NUM_POTS; i++){
|
||||
delete knobs[i];
|
||||
}
|
||||
|
||||
delete bmf;
|
||||
}
|
||||
|
||||
void Open9xSim::makeSnapshot(const FXDrawable* drawable)
|
||||
{
|
||||
// Construct and create an FXImage object
|
||||
|
|
|
@ -323,6 +323,11 @@ void *main_thread(void *)
|
|||
perMain();
|
||||
sleep(10/*ms*/);
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
luaClose();
|
||||
#endif
|
||||
|
||||
#ifdef SIMU_EXCEPTIONS
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -396,6 +401,14 @@ void StopEepromThread()
|
|||
sem_post(eeprom_write_sem);
|
||||
pthread_join(eeprom_thread_pid, NULL);
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
//TODO free semaphore eeprom_write_sem
|
||||
#else
|
||||
sem_destroy(eeprom_write_sem);
|
||||
free(eeprom_write_sem);
|
||||
#endif
|
||||
|
||||
if (fp) fclose(fp);
|
||||
}
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
|
@ -546,6 +559,13 @@ FRESULT f_opendir (DIR * rep, const TCHAR * name)
|
|||
return FR_OK;
|
||||
}
|
||||
|
||||
FRESULT f_closedir (DIR * rep)
|
||||
{
|
||||
TRACE("f_closedir(%p)", rep);
|
||||
simu::closedir((simu::DIR *)rep->fs);
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
FRESULT f_readdir (DIR * rep, FILINFO * fil)
|
||||
{
|
||||
if (!rep->fs) return FR_NO_FILE;
|
||||
|
|
|
@ -356,7 +356,9 @@ void simuSetTrim(uint8_t trim, bool state);
|
|||
void simuSetSwitch(uint8_t swtch, int8_t state);
|
||||
|
||||
void StartMainThread(bool tests=true);
|
||||
void StopMainThread();
|
||||
void StartEepromThread(const char *filename="eeprom.bin");
|
||||
void StopEepromThread();
|
||||
|
||||
extern const char *eepromFile;
|
||||
#if defined(PCBTARANIS) || defined(PCBACT)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue