cursor中malloc代码实现练习

cursor中类malloc代码实现的demo

记录一下

// Example: Explaining Code









/* Simply, ask the chat (Cmd+L/Ctrl+L) what this code does. */







#include 
#include  
#include 

typedef struct block_metadata {
   struct block_metadata *prev;
   struct block_metadata *next;
   size_t size;
} block;

block *head = NULL;

#ifndef ALLOC_UNIT
#define ALLOC_UNIT 3*sysconf( _SC_PAGESIZE )
#endif

#ifndef MIN_DEALLOC
#define MIN_DEALLOC 1 * sysconf(_SC_PAGESIZE)
#endif

#define BLOCK_MEM( ptr ) ( void * )( (unsigned long)ptr + sizeof( block ) )
#define BLOCK_HEADER( ptr ) ( void * )( (unsigned long)ptr - sizeof( block ) )

void stats( char * stage ) {
   printf( "Program break at %s : %ld \n", stage, sbrk( 0 ) );

   block *ptr = head;
   while( ptr ) {
      printf( "block addr: %ld, size: %ld \n", ptr, ptr->size );
      ptr = ptr->next;
   }
}

block * splitBlock( block *b, size_t size ) {
   block *newBlock;
   newBlock = (block *) ( (unsigned long)b + sizeof( block ) + size );
   newBlock->size = b->size - ( sizeof( block ) + size );
   b->size = size;
   return newBlock;
}

void addToFreeList( block *freeBlock ) {
   printf( "Adding %ld with size %ld to free list \n", freeBlock,
           freeBlock->size );
   freeBlock->next = NULL;
   freeBlock->prev = NULL;
   if( !head || (unsigned long) head >= (unsigned long) freeBlock ) {
      if( head ) {
         head->prev = freeBlock;
      }
      freeBlock->next = head;
      head = freeBlock;
      return;
   }

   block *ptr = head;
   while( ptr->next && (unsigned long) ptr->next < (unsigned long) freeBlock ) {
      ptr = ptr->next;
   }
   freeBlock->next = ptr->next;
   freeBlock->prev = ptr;
   ( ptr->next )->prev = freeBlock;
   ptr->next = freeBlock;
   return;
}

void removeFromFreeList( block * b ) {
   if( !b->prev ) {
      if( b->next ) {
         head = b->next;
      } else {
         head = NULL;
      }
   } else {
      b->prev->next = b->next;
   }
   if( b->next ) {  
      b->next->prev = b->prev;
   }
}

void * _malloc( size_t size ) {
   block *ptr = head;
   while( ptr ) {
      if( ptr->size >= size ) {
         removeFromFreeList( ptr );
         if( ptr->size == size ) {
            return BLOCK_MEM( ptr );
         }
         block *newBlock = splitBlock( ptr, size );
         addToFreeList( newBlock );
         return BLOCK_MEM( ptr );
      }
      ptr = ptr->next;
   }

   size_t alloc_size;
   if( size >= ALLOC_UNIT ) {
      alloc_size = size + sizeof( block );
   } else {
      alloc_size = ALLOC_UNIT;
   }

   ptr = sbrk( alloc_size );
   if( !ptr ) {
      printf( "Failed to alloc %d \n", alloc_size );
   }
   ptr->prev = NULL;
   ptr->next = NULL;
   ptr->size = alloc_size - sizeof( block );

   if( alloc_size > size + sizeof( block ) ){
      block *newBlock = splitBlock( ptr, size );
      addToFreeList( newBlock );
   }
   return BLOCK_MEM( ptr );
}

void scanAndCoalesce() {
   block *curr = head;
   unsigned long curr_addr, next_addr;
   while( curr->next ) {
      curr_addr = ( unsigned long ) curr;
      next_addr = ( unsigned long ) curr->next;
      if( curr_addr + sizeof( block ) + curr->size == next_addr ) {
         curr->size += curr->next->size + sizeof( block );
         curr->next = curr->next->next;
         if( curr->next->next ) {
            curr->next->next->prev = curr;
         } else {
            break;
         }
      }
      curr = curr->next;
   }
   stats( "after merge" );
   unsigned long program_break = (unsigned long) sbrk(0);
   if( program_break == 0 ) {
      printf( "failed to retrive program break\n" );
      return;
   }
   curr_addr = ( unsigned long ) curr;
   if( curr_addr + curr->size + sizeof( block ) == program_break
       && curr->size >= MIN_DEALLOC ) {
      removeFromFreeList( curr );
      if( brk( curr ) != 0 ) {
         printf( "error freeing memory \n" );
      }
   }
}

void _free( void * addr ) {
   block *block_addr = BLOCK_HEADER( addr );
   addToFreeList( block_addr );
   stats( "before coalesing " );
   scanAndCoalesce();
}

void cleanup() {
   printf( "Cleaning up memory ...\n" );
   if( head != NULL ) {
      if( brk( head ) != 0 ) {
         printf( "Failed to cleanup memory" );
      }
   }
   head = NULL;
}

int main() {
   atexit( cleanup );

   printf( "Malloc implementation\n" );

   stats( "beginning" );
   int *p1 =_malloc( 64 );
   stats( "after allocating 64 bytes" );
   int *p2 = _malloc( 1 );
   _free( p1 );
   return 0;
}

你可能感兴趣的:(c语言,链表,linux)