kmalloc/kfree ...

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

kmalloc/kfree ...

Post by xyjamepa »

Hi...

I've been working on my memory manager for a while and now
I got to point when I'm working on my kmalloc/kfree,
so guys I would like to see your viewpoint about this functions..
are they efficient enough,for using in the rest of my os?

What do you think?

Code: Select all

#define MALLOC_MAGIC	0x6D92  /* must be < 0x8000 */

typedef struct _malloc
{
 size_t size;			//4 bytes
 struct _malloc *next;		//4 bytes
 unsigned magic : 15 ;		//4 bytes
 unsigned used : 1 ;		
} malloc_t;

static malloc_t *_kheap_bot, *_kheap_top;

/**********************************************/
void *kbrk(int incr)
{
 static unsigned char *brk;
 void *ret;
 physaddr_t paddr;
 virtaddr_t vaddr;
 extern char end;
 if(brk==NULL)
  {
   brk=(unsigned char)&end;		//kernel end
   printf("Initializing the Heap...\n");
  }
 ret=brk;
 if(incr>0)
   incr+=(page_size-1);

 incr &=-page_size;

 if(incr<0)
    return brk;
  
 for(vaddr=(virtaddr_t)brk;vaddr<(virtaddr_t)brk+incr;vaddr+=page_size)
  {
   paddr=allocframe(0);//alloc physical page 4K
  
   //error no enough memory
   if(!paddr)
     return nomem;
  
   map(vaddr,paddr,write);   //map the page to a virtual address    
 
  }
 brk=brk+incr;
 return ret;

}

void *kmalloc(size_t size)
{
 size_t total_size;
 malloc_t *blk;
 if(size==0)
    return NULL;
 total_size=size+sizeof(malloc_t);
 
 /* heap does not exist yet*/
 
 if(_kheap_bot==NULL)
  {
    blk=kbrk(total_size);
    if(blk==-1)
       return NULL;
 
     _kheap_bot=_kheap_top=blk;
     blk->size=size;
     blk->next=NULL;
     blk->magic=MALLOC_MAGIC;
     blk->used=1;
     return (char *)blk + sizeof(malloc_t);
  }
 /* heap is already exist so...
    search the heap for free block
    first fit algorithem */
  
 for(blk=_kheap_bot;blk!=NULL;blk=blk->next)
  {
    if(!blk->used && total_size<=blk->size)
      break;
  }
 
 /* found a block */
 if(blk!=NULL)
  {
    malloc_t *new_blk;
    new_blk=(malloc_t *)((char *)blk+total_size);

 /* point to new empty block and down size it */
   
    new_blk->used=0;
    new_blk->size=blk->size-total_size;
    new_blk->next=blk->next;
    new_blk->magic=MALLOC_MAGIC;
 
 /* set _kheap_top if necessary */
   
    if(new_blk->next=NULL)
         _kheap_top=new_blk;
 /* point to new used block and set it */
    
    blk->used=1;
    blk->size=size;
    blk->next=new_blk;
    blk->magic=MALLOC_MAGIC;
    return (char *)blk+sizeof(malloc_t); 
   
  }

 /* not found any block so enlarge the heap */
  blk=kbrk(total_size);
  if((int)blk==-1)
     return NULL ;//no more memory
  blk->used=1;
  blk->size=size;
  blk->next=NULL;
  blk->magic=MALLOC_MAGIC;
 
/* this block is the new end of the heap */
  
 _kheap_top->next=blk;
 _kheap_top=blk;
 return (char *)blk+sizeof(malloc_t);

}

void kfree(void *blk)
{
  malloc_t *t_blk;
  
 /*get the actual address of the block*/
 
 blk=(char *)blk-sizeof(malloc_t);
 t_blk=(malloc_t *)blk;
 /* bad magic value */
 if(t_blk->magic!=MALLOC_MAGIC)
     return;
 
 /* search for the block */
  
  for(t_blk=_kheap_bot;t_blk!=NULL;t_blk=t_blk->next)
   {
      if(t_blk==blk)
         break;
   }
 
 /* not found the block */
  
  if(t_blk==NULL)
    return;

 /* found the block so free it */
  
  t_blk->used=0;
  
  for(t_blk= _kheap_bot;t_blk!=NULL;t_blk=t_blk->next)
   {
  
     while(!t_blk->used && (t_blk->next!=NULL) && !t_blk->next->used)
      {
        t_blk->size+=sizeof(malloc_t)+ t_blk->next->size;
        t_blk->next=t_blk->next->next;
      }  
  
   }//End for
  

}
Thanx.
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

Yes that looks like a fine malloc implementation to begin with. Remember that you can always trade out that malloc for an another one when you get further down the road.
tgo
Posts: 2
Joined: Fri Jul 06, 2007 3:00 pm

Re: kmalloc/kfree ...

Post by tgo »

abuashraf wrote: void *kmalloc(size_t size)
{
size_t total_size;
malloc_t *blk;
if(size==0)
return NULL;
total_size=size+sizeof(malloc_t); *********

Sorry to be a pain but i thought i should comment on this. You only check size for 0. You should check the addition of size+sizeof() since this addition can wrap back around to 0 and cause you issues if the size supplied is large enough and most os'es have a few places where users can reliably enough control a integer used for these malloc calls.
abuashraf wrote: .............
/* heap is already exist so...
search the heap for free block
first fit algorithem */

for(blk=_kheap_bot;blk!=NULL;blk=blk->next)
{
if(!blk->used && total_size<=blk->size)
break;
}

/* found a block */
if(blk!=NULL)
{
malloc_t *new_blk;
new_blk=(malloc_t *)((char *)blk+total_size);

......

new_blk->size=blk->size-total_size;
new_blk->next=blk->next;
new_blk->magic=MALLOC_MAGIC;

............

blk->size=size;

......

KFREE:
for(t_blk= _kheap_bot;t_blk!=NULL;t_blk=t_blk->next)
{

while(!t_blk->used && (t_blk->next!=NULL) && !t_blk->next->used)
{
----> t_blk->size+=sizeof(malloc_t)+ t_blk->next->size; <----
t_blk->next=t_blk->next->next;
}
these quotes show places where issues might arise if "size" was say 0xffffffff making "total_size" 16 and "size" 0xffffffff.
Post Reply