lua: Switch memory allocator from dl to tlsf

Instead of providing yet another memory allocator implementation
use tlsf and simply link tlsf library.

Another small improvement is to *grow* memory pool by grabbing
audiobuffer instead of just switching to use audiobuf exclusively.
Tested with simple lua 'memory eater' script.

This patch extends tlsf lib slightly. You can provide
void *get_new_area(size_t * size) function which will override
weak dummy implementation provided in lib itself. This allows to
automaticaly initialize memory pool as well as grow memory
pool if needed (for example grab audiobuffer when pluginbuffer
is exhaused).

Change-Id: I841af6b6b5bbbf546c14cbf139a7723fbb982f1b
This commit is contained in:
Marcin Bukat 2013-08-22 12:12:47 +02:00
parent b2e80edd16
commit a2a2e14e0d
10 changed files with 50 additions and 5173 deletions

View file

@ -9,13 +9,3 @@ version 0.31 which is licensed under the GPL version 2:
strtol.c
strtoul.c
strstr.c
The malloc routine is Doug Lea's malloc with the following license:
Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee)
This is a version (aka dlmalloc) of malloc/free/realloc written by
Doug Lea and released to the public domain, as explained at
http://creativecommons.org/licenses/publicdomain. Send questions,
comments, complaints, performance data, etc to dl@cs.oswego.edu

View file

@ -28,7 +28,7 @@ lvm.c
lzio.c
rockaux.c
rocklib.c
rockmalloc.c
tlsf_helper.c
fscanf.c
gmtime.c
strcspn.c

View file

@ -30,7 +30,7 @@ else
ROCKS += $(LUA_BUILDDIR)/lua.rock
endif
$(LUA_BUILDDIR)/lua.rock: $(LUA_OBJ) $(LUA_BUILDDIR)/actions.lua $(LUA_BUILDDIR)/buttons.lua $(LUA_BUILDDIR)/rocklib_aux.o
$(LUA_BUILDDIR)/lua.rock: $(LUA_OBJ) $(TLSFLIB) $(LUA_BUILDDIR)/actions.lua $(LUA_BUILDDIR)/buttons.lua $(LUA_BUILDDIR)/rocklib_aux.o
$(LUA_BUILDDIR)/actions.lua: $(LUA_OBJ) $(LUA_SRCDIR)/action_helper.pl
$(call PRINTS,GEN $(@F))$(CC) $(PLUGINFLAGS) $(INCLUDES) -E $(APPSDIR)/plugins/lib/pluginlib_actions.h | $(LUA_SRCDIR)/action_helper.pl > $(LUA_BUILDDIR)/actions.lua
@ -45,13 +45,13 @@ $(LUA_BUILDDIR)/rocklib_aux.c: $(APPSDIR)/plugin.h $(LUA_OBJ) $(LUA_SRCDIR)/rock
$(LUA_BUILDDIR)/rocklib_aux.o: $(LUA_BUILDDIR)/rocklib_aux.c
$(call PRINTS,CC $(<F))$(CC) $(INCLUDES) $(PLUGINFLAGS) -I $(LUA_SRCDIR) -c $< -o $@
$(LUA_BUILDDIR)/lua.refmap: $(LUA_OBJ)
$(LUA_BUILDDIR)/lua.refmap: $(LUA_OBJ) $(TLSFLIB)
$(LUA_OUTLDS): $(PLUGIN_LDS) $(LUA_BUILDDIR)/lua.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(LUA_BUILDDIR)/lua.refmap))
$(LUA_BUILDDIR)/lua.ovl: $(LUA_OBJ) $(LUA_OUTLDS)
$(LUA_BUILDDIR)/lua.ovl: $(LUA_OBJ) $(TLSFLIB) $(LUA_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \
$(filter %.o, $^) \
$(filter %.a, $+) \

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@
#define _ROCKCONF_H_
#include "plugin.h"
#include <tlsf.h>
#undef LUAI_THROW
#undef LUAI_TRY
@ -40,9 +41,6 @@
#define luai_jmpbuf jmp_buf
extern char curpath[MAX_PATH];
void* dlmalloc(size_t bytes);
void *dlrealloc(void *ptr, size_t size);
void dlfree(void *ptr);
struct tm *gmtime(const time_t *timep);
long strtol(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *str, char **endptr, int base);
@ -54,8 +52,9 @@ long lpow(long x, long y);
#define pow lpow
/* Simple substitutions */
#define realloc dlrealloc
#define free dlfree
#define malloc tlsf_malloc
#define realloc tlsf_realloc
#define free tlsf_free
#define memchr rb->memchr
#define snprintf rb->snprintf
#define strcat rb->strcat

View file

@ -522,7 +522,7 @@ static void fill_text_message(lua_State *L, struct text_message * message,
int i;
luaL_checktype(L, pos, LUA_TTABLE);
int n = luaL_getn(L, pos);
const char **lines = (const char**) dlmalloc(n * sizeof(const char*));
const char **lines = (const char**) tlsf_malloc(n * sizeof(const char*));
if(lines == NULL)
luaL_error(L, "Can't allocate %d bytes!", n * sizeof(const char*));
for(i=1; i<=n; i++)
@ -548,11 +548,11 @@ RB_WRAP(gui_syncyesno_run)
enum yesno_res result = rb->gui_syncyesno_run(&main_message, yes, no);
dlfree(main_message.message_lines);
tlsf_free(main_message.message_lines);
if(yes)
dlfree(yes_message.message_lines);
tlsf_free(yes_message.message_lines);
if(no)
dlfree(no_message.message_lines);
tlsf_free(no_message.message_lines);
lua_pushinteger(L, result);
return 1;
@ -571,7 +571,7 @@ RB_WRAP(do_menu)
start_selected = luaL_optint(L, 3, 0);
n = luaL_getn(L, 2);
items = (const char**) dlmalloc(n * sizeof(const char*));
items = (const char**) tlsf_malloc(n * sizeof(const char*));
if(items == NULL)
luaL_error(L, "Can't allocate %d bytes!", n * sizeof(const char*));
for(i=1; i<=n; i++)
@ -587,7 +587,7 @@ RB_WRAP(do_menu)
int result = rb->do_menu(&menu, &start_selected, NULL, false);
dlfree(items);
tlsf_free(items);
lua_pushinteger(L, result);
return 1;

View file

@ -24,7 +24,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "rocklib.h"
#include "rockmalloc.h"
#include "luadir.h"
@ -165,8 +164,6 @@ enum plugin_status plugin_start(const void* parameter)
status = docall(L);
}
dlmalloc_stats();
if (status) {
DEBUGF("%s\n", lua_tostring(L, -1));
rb->splashf(5 * HZ, "%s", lua_tostring(L, -1));

View file

@ -1,63 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 Dan Everton (safetydan)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "plugin.h"
#include "rockmalloc.h"
#include "malloc.c"
void *rocklua_morecore(int size)
{
static char *sbrk_top = NULL;
static ssize_t total_size = 0;
void *ptr = 0;
if (size > 0) {
size = size + 4 - (size % 4);
if (sbrk_top == NULL) {
sbrk_top = rb->plugin_get_buffer((size_t *) &total_size);
}
if (sbrk_top == NULL || size + 4 > abs(total_size)) {
/* Try the audio buffer */
sbrk_top = rb->plugin_get_audio_buffer((size_t *) &total_size);
if(sbrk_top == NULL || size + 4 > abs(total_size)) {
printf("malloc failed for %d!\n", size);
return (void *) MFAIL;
}
}
ptr = sbrk_top + 4;
*((unsigned int *) sbrk_top) = size;
sbrk_top += size + 4;
total_size -= size + 4;
return ptr;
} else if (size < 0) {
/* we don't currently support shrink behavior */
return (void *) MFAIL;
} else {
return sbrk_top;
}
}

View file

@ -5,9 +5,8 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 Dan Everton (safetydan)
* Copyright (C) 2013 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -19,28 +18,31 @@
*
****************************************************************************/
#ifndef _ROCKMALLOC_H_
#define _ROCKMALLOC_H_
#include "plugin.h"
#include <tlsf.h>
#undef WIN32
#undef _WIN32
#define LACKS_UNISTD_H
#define LACKS_SYS_PARAM_H
#define LACKS_SYS_MMAN_H
#define LACKS_STRINGS_H
#define INSECURE 1
#define USE_DL_PREFIX 1
#define MORECORE_CANNOT_TRIM 1
#define HAVE_MMAP 0
#define HAVE_MREMAP 0
#define NO_MALLINFO 1
#define ABORT ((void) 0)
/* #define DEBUG */
#define MORECORE rocklua_morecore
void *get_new_area(size_t *size)
{
static char *pluginbuf_ptr = NULL;
static char *audiobuf_ptr = NULL;
void *rocklua_morecore(int size);
void dlmalloc_stats(void);
if (pluginbuf_ptr == NULL)
{
pluginbuf_ptr = rb->plugin_get_buffer(size);
#define printf DEBUGF
/* kill tlsf signature if any */
memset(pluginbuf_ptr, 0, 4);
#endif
return pluginbuf_ptr;
}
if (audiobuf_ptr == NULL)
{
/* grab audiobuffer */
audiobuf_ptr = rb->plugin_get_audio_buffer(size);
return audiobuf_ptr;
}
return ((void *) ~0);
}

View file

@ -395,6 +395,14 @@ static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl
set_bit (_fl, &_tlsf -> fl_bitmap); \
} while(0)
#if defined(ROCKBOX)
void * __attribute__((weak)) get_new_area(size_t * size)
{
(void)size;
return ((void *) ~0);
}
#endif
#if USE_SBRK || USE_MMAP
static __inline__ void *get_new_area(size_t * size)
{
@ -615,7 +623,7 @@ void *tlsf_malloc(size_t size)
/******************************************************************/
void *ret;
#if USE_MMAP || USE_SBRK
#if USE_MMAP || USE_SBRK || defined(ROCKBOX)
if (!mp) {
size_t area_size;
void *area;
@ -657,7 +665,7 @@ void *tlsf_realloc(void *ptr, size_t size)
/******************************************************************/
void *ret;
#if USE_MMAP || USE_SBRK
#if USE_MMAP || USE_SBRK || defined(ROCKBOX)
if (!mp) {
return tlsf_malloc(size);
}
@ -705,7 +713,7 @@ void *malloc_ex(size_t size, void *mem_pool)
so they are not longer valid when the function fails */
b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
#if USE_MMAP || USE_SBRK
#if USE_MMAP || USE_SBRK || defined(ROCKBOX)
if (!b) {
size_t area_size;
void *area;