1
0
Fork 0
forked from len0rd/rockbox

Moved the malloc system into the firmware/malloc/ directory, removed the

implementation files from the test/malloc/ directory, leaving only test
files there.

Added headers, corrected a few minor documenational errors.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@571 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Daniel Stenberg 2002-05-14 08:19:57 +00:00
parent bbdeba6d8c
commit f143fd8e36
14 changed files with 214 additions and 77 deletions

40
firmware/malloc/Makefile Normal file
View file

@ -0,0 +1,40 @@
# __________ __ ___.
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
# $Id$
#
# Copyright (C) 2002 by Daniel Stenberg
#
# All files in this archive are subject to the GNU General Public License.
# See the file COPYING in the source tree root for full license agreement.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
TARGET = libdmalloc.a
LIBOBJS = dmalloc.o bmalloc.o bysize.o
# define this to talk a lot in runtime
# -DDEBUG_VERBOSE
CFLAGS = -g -Wall -DDEBUG
CC = gcc
AR = ar
LDFLAGS = -L. -ldmalloc
all: $(TARGET)
clean:
rm -f core *~ $(TARGET) $(LIBOBJS)
$(TARGET): $(LIBOBJS)
$(AR) ruv $(TARGET) $(LIBOBJS)
bmalloc.o: bmalloc.c bysize.h
bysize.o: bysize.c
dmalloc.o: dmalloc.c

View file

@ -2,7 +2,7 @@ Package: dbestfit - a dynamic best-fit memory allocator
Date: 1996 - 2002 Date: 1996 - 2002
Version: 3.3 Version: 3.3
Author: Daniel Stenberg <daniel@haxx.se> Author: Daniel Stenberg <daniel@haxx.se>
License: MIT License: MIT originally, files in the Rockbox project are GPL licensed.
I wrote the dmalloc part for small allocation sizes to improve the behavior I wrote the dmalloc part for small allocation sizes to improve the behavior
of the built-in (first-fit) allocator found in pSOS, during late 1996 and of the built-in (first-fit) allocator found in pSOS, during late 1996 and

View file

@ -1,6 +1,6 @@
===================================== ====================================
Memory Allocation Algorithm Theories. Memory Allocation Algorithm Theories
===================================== ====================================
GOAL GOAL
It is intended to be a 100% working memory allocation system. It should be It is intended to be a 100% working memory allocation system. It should be
@ -15,8 +15,8 @@ GOAL
TERMINOLOGY TERMINOLOGY
FRAGMENT - small identically sized parts of a larger BLOCK, they are when FRAGMENT - small identically sized parts of a larger BLOCK, they are _not_
travered in lists etc _not_ allocated. allocated when traversed in lists etc
BLOCK - large memory area, if used for FRAGMENTS, they are linked in a BLOCK - large memory area, if used for FRAGMENTS, they are linked in a
lists. One list for each FRAGMENT size supported. lists. One list for each FRAGMENT size supported.
TOP - head struct that holds information about and points to a chain TOP - head struct that holds information about and points to a chain
@ -39,12 +39,12 @@ MEMORY SYSTEM
ALLOC ALLOC
* Small allocations are "aligned" upwards to a set of preset sizes. In the * Small allocations are "aligned" upwards to a set of preset sizes. In the
current implementation I use 20, 28, 52, 116, 312, 580, 812, 2028 bytes. current implementation I use 20, 28, 52, 116, 312, 580, 1016, 2032 bytes.
Memory allocations of these sizes are refered to as FRAGMENTS. Memory allocations of these sizes are referred to as FRAGMENTS.
(The reason for these specific sizes is the requirement that they must be (The reason for these specific sizes is the requirement that they must be
32-bit aligned and fit as good as possible within 4060 bytes.) 32-bit aligned and fit as good as possible within 4064 bytes.)
* Allocations larger than 2028 will get a BLOCK for that allocation only. * Allocations larger than 2032 will get a BLOCK for that allocation only.
* Each of these sizes has it's own TOP. When a FRAGMENT is requested, a * Each of these sizes has it's own TOP. When a FRAGMENT is requested, a
larger BLOCK will be allocated and divided into many FRAGMENTS (all of the larger BLOCK will be allocated and divided into many FRAGMENTS (all of the
@ -52,12 +52,12 @@ MEMORY SYSTEM
the same size. Each BLOCK has a 'number of free FRAGMENTS' counter and so the same size. Each BLOCK has a 'number of free FRAGMENTS' counter and so
has each TOP (for the entire chain). has each TOP (for the entire chain).
* A BLOCK is around 4060 bytes plus the size of the information header. This * A BLOCK is around 4064 bytes plus the size of the information header. This
size is adjusted to make the allocation of the big block not require more size is adjusted to make the allocation of the big block not require more
than 4096 bytes. (This might not be so easy to be sure of, if you don't than 4096 bytes. (This might not be so easy to be sure of, if you don't
know how the big-block system works, but the BMALLOC system uses an know how the big-block system works, but the BMALLOC system uses an
extra header of 12 bytes and the header for the FRAGMENT BLOCK is 20 bytes extra header of 12 bytes and the header for the FRAGMENT BLOCK is 20 bytes
in a general 32-bit unix environment.) in a general 32-bit environment.)
* In case the allocation of a BLOCK fails when a FRAGMENT is required, the * In case the allocation of a BLOCK fails when a FRAGMENT is required, the
next size of FRAGMENTS will be checked for a free FRAGMENT. First when the next size of FRAGMENTS will be checked for a free FRAGMENT. First when the
@ -122,16 +122,16 @@ MEMORY SYSTEM
no real gain in increasing the size of the align. no real gain in increasing the size of the align.
* We link *all* pieces of memory (AREAS), free or not free. We keep the list * We link *all* pieces of memory (AREAS), free or not free. We keep the list
in address order and thus when a FREE() occurs we know instanstly if there in address order and thus when a FREE() occurs we know instantly if there
are FREE CHUNKS wall-to-wall. No list "travels" needed. Requires some are FREE CHUNKS wall-to-wall. No list "travels" needed. Requires some
extra space in every allocated BLOCK. Still needs to put the new CHUNK in extra space in every allocated BLOCK. Still needs to put the new CHUNK in
the right place in size-sorted list/tree. All memory areas, allocated or the right place in size-sorted list/tree. All memory areas, allocated or
not, contain the following header: not, contain the following header:
- size of this memory area - size of this memory area (31 bits)
- FREE status - FREE status (1 bit)
- pointer to the next AREA closest in memory - pointer to the next AREA closest in memory (32 bits)
- pointer to the prev AREA closest in memory - pointer to the prev AREA closest in memory (32 bits)
(12 bytes) (Totally 12 bytes)
* Sort all FREE CHUNKS in size-order. We use a SPLAY TREE algorithm for * Sort all FREE CHUNKS in size-order. We use a SPLAY TREE algorithm for
maximum speed. Data/structs used for the size-sorting functions are kept maximum speed. Data/structs used for the size-sorting functions are kept
@ -154,7 +154,7 @@ MEMORY SYSTEM
REALLOC REALLOC
* There IS NO realloc() of large blocks, they are performed in the higher * There IS NO realloc() of large blocks, they are performed in the previous
layer (dmalloc). layer (dmalloc).

View file

@ -1,3 +1,21 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Daniel Stenberg
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
/***************************************************************************** /*****************************************************************************
* *
* Big (best-fit) Memory Allocation * Big (best-fit) Memory Allocation
@ -128,7 +146,7 @@ void add_blocktolists(struct BlockInfo *block,
/* yes, we are wall-to-wall with the higher CHUNK */ /* yes, we are wall-to-wall with the higher CHUNK */
if(temp->info&INFO_FREE) { if(temp->info&INFO_FREE) {
/* and the neighbour is even free, remove that one and enlarge /* and the neighbour is even free, remove that one and enlarge
ourselves, call add_pool() recursively and then escape */ ourselves, call add_blocktolists() recursively and then escape */
remove_block(temp); /* unlink 'temp' from list */ remove_block(temp); /* unlink 'temp' from list */

24
firmware/malloc/bmalloc.h Normal file
View file

@ -0,0 +1,24 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Daniel Stenberg
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
int bmalloc_add_pool(void *start, size_t size);
void bmalloc_status(void);
void *bmalloc(size_t size);
void bfree(void *ptr);

View file

@ -1,3 +1,21 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Daniel Stenberg
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
/***************************************************************************** /*****************************************************************************
* *
* Size-sorted list/tree functions. * Size-sorted list/tree functions.
@ -5,8 +23,7 @@
* Author: Daniel Stenberg * Author: Daniel Stenberg
* Date: March 7, 1997 * Date: March 7, 1997
* Version: 2.0 * Version: 2.0
* Email: Daniel.Stenberg@sth.frontec.se * Email: daniel@haxx.se
*
* *
* v2.0 * v2.0
* - Added SPLAY TREE functionality. * - Added SPLAY TREE functionality.

24
firmware/malloc/bysize.h Normal file
View file

@ -0,0 +1,24 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Daniel Stenberg
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
void bmalloc_remove_chunksize(void *data);
void bmalloc_insert_bysize(char *data, size_t size);
char *bmalloc_obtainbysize( size_t size);
#ifdef DEBUG
void bmalloc_print_sizes(void);
#endif

View file

@ -1,3 +1,21 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Daniel Stenberg
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
/***************************************************************************** /*****************************************************************************
* *
* Dynamic small-blocks Memory Allocation * Dynamic small-blocks Memory Allocation
@ -22,6 +40,8 @@
#include <stdlib.h> /* makes the PSOS complain on the 'size_t' typedef */ #include <stdlib.h> /* makes the PSOS complain on the 'size_t' typedef */
#endif #endif
#define BMALLOC /* we use our own big-malloc system */
#ifdef BMALLOC #ifdef BMALLOC
#include "bmalloc.h" #include "bmalloc.h"
#endif #endif
@ -132,8 +152,7 @@ struct MemInfo {
/* a little 'bc' script that helps us maximize the usage: /* a little 'bc' script that helps us maximize the usage:
- for 32-bit aligned addresses (SPARC crashes otherwise): - for 32-bit aligned addresses (SPARC crashes otherwise):
for(i=20; i<2040; i++) { a=4064/i; if(a*i >= 4060) { if(i%4==0) {i;} } } for(i=20; i<2040; i+=4) { a=4064/i; if(a*i >= 4060) { {i;} } }
I try to approximate a double of each size, starting with ~20. We don't do I try to approximate a double of each size, starting with ~20. We don't do
ODD sizes since several CPU flavours dump core when accessing such ODD sizes since several CPU flavours dump core when accessing such
@ -141,9 +160,9 @@ struct MemInfo {
happy with us. happy with us.
*/ */
short qinfo[]= { 20, 28, 52, 116, 312, 580, 1016, 2032}; const static short qinfo[]= {
/* 52 and 312 only make use of 4056 bytes, but without them there are too 20, 28, 52, 116, 312, 580, 1016, 2032
wide gaps */ };
#define MIN(x,y) ((x)<(y)?(x):(y)) #define MIN(x,y) ((x)<(y)?(x):(y))

35
firmware/malloc/dmalloc.h Normal file
View file

@ -0,0 +1,35 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Daniel Stenberg
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
void *dmalloc(size_t);
void dfree(void *);
void *drealloc(void *, size_t);
#define malloc(x) dmalloc(x)
#define free(x) dfree(x)
#define realloc(x,y) drealloc(x,y)
#define calloc(x,y) dcalloc(x,y)
/* use this to intialize the internals of the dmalloc engine */
void dmalloc_initialize(void);
#ifdef DEBUG
void dmalloc_status(void);
#endif

View file

@ -1,8 +1,4 @@
TARGET = libdmalloc.a
LIBOBJS = dmalloc.o bmalloc.o bysize.o
OBJS1 = mytest.o OBJS1 = mytest.o
TARGET1 = mytest TARGET1 = mytest
@ -14,20 +10,17 @@ TARGET3 = dmytest
# define this to talk a lot in runtime # define this to talk a lot in runtime
# -DDEBUG_VERBOSE # -DDEBUG_VERBOSE
CFLAGS = -g -DUNIX -DBMALLOC -Wall -DDEBUG CFLAGS = -g -Wall -DDEBUG -I../../malloc
CC = gcc CC = gcc
AR = ar AR = ar
LDFLAGS = -L. -ldmalloc LDFLAGS = -L../../malloc -ldmalloc
all: $(TARGET) $(TARGET1) $(TARGET2) $(TARGET3) all: $(TARGET1) $(TARGET2) $(TARGET3)
clean: clean:
rm -f core *~ $(TARGET) $(TARGET1) $(TARGET2) $(TARGET3) \ rm -f core *~ $(TARGET1) $(TARGET2) $(TARGET3) \
$(LIBOBJS) $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS1) $(OBJS2) $(OBJS3)
$(TARGET): $(LIBOBJS)
$(AR) ruv $(TARGET) $(LIBOBJS)
$(TARGET1): $(OBJS1) $(TARGET1): $(OBJS1)
$(CC) -g -o $(TARGET1) $(OBJS1) $(LDFLAGS) $(CC) -g -o $(TARGET1) $(OBJS1) $(LDFLAGS)
@ -38,14 +31,6 @@ $(TARGET2): $(OBJS2)
$(TARGET3): $(OBJS3) $(TARGET3): $(OBJS3)
$(CC) -g -o $(TARGET3) $(OBJS3) $(LDFLAGS) $(CC) -g -o $(TARGET3) $(OBJS3) $(LDFLAGS)
bmalloc.o: bmalloc.c bysize.h dmytest.o: dmytest.c
bysize.o: bysize.c
dmalloc.o: dmalloc.c
dmytest.o: dmytest.c dmalloc.h bmalloc.h
Malloc.o: Malloc.c Malloc.o: Malloc.c
mytest.o: mytest.c bmalloc.h mytest.o: mytest.c
tgz:
@(dir=`pwd`;name=`basename $$dir`;echo Creates $$name.tar.gz; cd .. ; \
tar -cf $$name.tar `cat $$name/FILES | sed "s:^/:$$name/:g"` ; \
gzip $$name.tar ; chmod a+r $$name.tar.gz ; mv $$name.tar.gz $$name/)

View file

@ -26,7 +26,7 @@ kommentaren p
*/ */
/*#undef BMALLOC*/ #define BMALLOC /* go go go */
#ifdef BMALLOC #ifdef BMALLOC
#include "dmalloc.h" #include "dmalloc.h"
@ -162,7 +162,7 @@ int main(void)
} }
output: output:
if (out_of_memory || !(count%DISPLAY_WHEN)) { if (out_of_memory || !(count%DISPLAY_WHEN)) {
printf("(%d) malloc %d, realloc %d, free %d, total size %d\n", printf("(%ld) malloc %ld, realloc %ld, free %ld, total size %ld\n",
count, count_malloc, count_realloc, count_free, total_memory); count, count_malloc, count_realloc, count_free, total_memory);
{ {
int count; int count;
@ -175,7 +175,7 @@ int main(void)
} }
if (out_of_memory) { if (out_of_memory) {
if(out_of_memory) if(out_of_memory)
printf("Couldn't get %d bytes\n", out_of_memory); printf("Couldn't get %ld bytes\n", out_of_memory);
dmalloc_status(); dmalloc_status();
bmalloc_status(); bmalloc_status();

View file

@ -1,6 +0,0 @@
int bmalloc_add_pool(void *start, size_t size);
void bmalloc_status(void);
void *bmalloc(size_t size);
void bfree(void *ptr);

View file

@ -1,6 +0,0 @@
void bmalloc_remove_chunksize(void *data);
void bmalloc_insert_bysize(char *data, size_t size);
char *bmalloc_obtainbysize( size_t size);
#ifdef DEBUG
void bmalloc_print_sizes(void);
#endif

View file

@ -1,13 +0,0 @@
void *dmalloc(size_t);
void dfree(void *);
void *drealloc(void *, size_t);
#define malloc(x) dmalloc(x)
#define free(x) dfree(x)
#define realloc(x,y) drealloc(x,y)
#define calloc(x,y) dcalloc(x,y)
/* use this to intialize the internals of the dmalloc engine */
void dmalloc_initialize(void);