Rockbox.org home
release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide



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
aaa