Rockbox mail archive
Subject: Re: another 8MB upgrade success story
From: Joaquim Carvalho (jdc_at_x64.com)
Date: 2003-03-21
On Fri, 2003-03-21 at 06:25, Daniel Stenberg wrote:
> On Thu, 20 Mar 2003, Gerald Clark wrote:
>
> > And the benefit of doing like this would be... ?
> >
> > The ability to allocate different sized blocks of memory based on total
> > size or config values.
>
> Yes, but using your suggested approach we would need to reboot in order to
> use new config values. I'd hate something like that. Would be like Windows. I
> would vote against such a system introduced in Rockbox.
As it is now you have to re-compile, enter USB mode, upload the
software and finally reboot!
>
> > You have to allocate your buffers now, don't you?
>
> If declaring a static buffer means allocate to you, then yes.
>
> > The statement was made that dynamic allocation was too complicated .
>
> Yes. Too complicated for what we get. We already have a malloc()
> implementation so its not the absense of code that has lead to this decision.
>
> > That is only true if you also implement release and reuse of memory. If you
> > only allow for dynamically sized allocation from the total memory pool,
> > without realloc() or free() type functions, then it does not have to be
> > difficult at all.
>
> It isn't difficult, it is complicated and needs lots of code.
Here's my contribution: the malloc, free and defrag functions
I wrote for X64, the company I work for. X64 agrees to make
this code opensource so feel free to use it. It's on the small
side so I'll post it right here.
Joaquim
#IF compile_malloc 1 ;
#IF debug_malloc 1 ;
show_memory_blocks()
{
static struct memory_block_struct *block;
cls();
block=end_all_program_blocks;
do
{
// print_string("Owner: ");
// print_number(block->owner);
// new_line();
print_string("Address: ");
print_number(block->address);
new_line();
// print_string("Data: ");
// print_number(block->data);
// new_line();
print_string("Size: ");
print_number(block->size);
new_line();
// print_string("Advance: ");
// print_number(block->advance);
// new_line();
if( block->advance )
{
block = block->address + block->advance ;
new_line();
}
else
{
break;
}
}
while( 1 );
browse_screen();
}
#ENDIF ;
init_memory_allocation()
{
static struct memory_block_struct *block;
block=end_all_program_blocks;
if( read_cpu_register32(CPU_STACK) > (128*1024) )
{
block->size=512*1024-256-1024-block->data;
//block->size=512*1024-256-1024-block->data;
block->advance=0;
block->owner=0;
}
else
{
block->size=128*1024-256-1024-block->data;
//block->size=128*1024-256-1024-block->data;
block->advance=0;
block->owner=0;
}
#IF debug_malloc 1 ;
cursor(0);
set_display(0);
print_number((block->address));
new_line();
print_number(block->data);
getch();
#ENDIF ;
}
malloc2(int size)
{
static int direction;
static struct memory_block_struct *fit;
static struct memory_block_struct *block;
block=end_all_program_blocks;
fit=0;
do
{
if( !block->owner )
{
if( block->size >= size )
{
fit=block;
if(direction)
{
break;
}
}
}
if( block->advance )
{
block = block->address + block->advance ;
}
else
{
break;
}
}
while( 1 );
if(fit)
{
if( fit->size - size <= fit->data - fit->address )
{
fit->owner = 1 ;
return( fit->data );
}
if( direction )
{
block = fit->data + size ;
block->size = fit->data + fit->size - block->data ;
if( fit->advance )
{
block->advance = fit->address + fit->advance - block->address ;
}
else
{
block->advance = 0 ;
}
block->owner = 0 ;
fit->size = size ;
fit->advance = block->address - fit->address ;
fit->owner = 2 ;
return( fit->data ) ;
}
else
{
block = fit->address + fit->size - size ;
fit->size = block->address - fit->data ;
block->size = size ;
if( fit->advance )
{
fit->advance = block->address - fit->address ;
block->advance = block->size + block->data - block->address ;
}
else
{
fit->advance = block->address - fit->address ;
block->advance = 0 ;
}
block->owner = 1 ;
return(block->data);
}
}
return(0);
}
free(char *data)
{
static struct memory_block_struct *block;
block = data - block->data + block->address;
if( block->owner )
{
block->owner = 0;
defrag_memory();
return(0);
}
else
{
error("Allocation Error");
}
}
defrag_memory()
{
static struct memory_block_struct *block;
static struct memory_block_struct *next_block;
block=end_all_program_blocks;
while( block->advance )
{
next_block = block->address + block->advance ;
if( block->owner == 0 && next_block->owner == 0 )
{
block->size = next_block->data + next_block->size - block->data;
if( next_block->advance )
{
block->advance = block->size + block->data - block->address ;
}
else
{
block->advance = 0 ;
}
}
else
{
block=next_block;
}
}
}
malloc(int size)
{
static char *ptr;
static int dont_halt_on_error;
if(ptr=malloc2(size))
{
return(ptr);
}
else
{
defrag_memory();
if(ptr=malloc2(size))
{
return(ptr);
}
else
{
if(!dont_halt_on_error)
{
error("Memory full!");
}
return(0);
}
}
}
/*
advance_block()
{
static struct memory_block_struct *block;
static struct memory_block_struct *next_block;
memcpy( block->address + offset, block->address, block
*/
#ENDIF ;
Page was last modified "Jan 10 2012" The Rockbox Crew
|