Ejemplo n.º 1
0
/**
 * Allocates a region on the kernel's heap
 */
void *kalloc(uint32_t size)
{			
	//kc_printf("Alloc\n");
	struct heap_block_hdr_t *p, *prevp;
	unsigned nunits;

	nunits = (size + sizeof(struct heap_block_hdr_t) - 1) / sizeof(struct heap_block_hdr_t) + 1;

	if((prevp = kernel_heap_free) == NULL) {
		kernel_heap_free_base.block_size = 0;
		kernel_heap_free = prevp = &kernel_heap_free_base;
		kernel_heap_free_base.next_block = kernel_heap_free;
	}

	for(p = prevp->next_block; ; prevp = p, p = p->next_block)
	{
		if(p->block_size >= nunits) {

			if(p->block_size == nunits) {
				prevp->next_block = p->next_block;
			} else {
				// Not all units required, relocate header
				p->block_size -= nunits;
				p += p->block_size;
				p->block_size = nunits;
			}

			kernel_heap_free = prevp;
			//kc_printf("OK (%x)\n", (uint32_t) (p+1));
			return (void *) (p + 1);
		}

		if(p == kernel_heap_free)
			if(kbrk() == NULL)
				return NULL;
	}
}
Ejemplo n.º 2
0
/*****************************************************************************
kmalloc() and kfree() use g_heap_bot, but not g_kbrk nor g_heap_top
*****************************************************************************/
void *kmalloc(size_t size)
{
	unsigned total_size;
	malloc_t *m, *n;
	int delta;

	if(size == 0)
		return NULL;
	total_size = size + sizeof(malloc_t);
/* search heap for free block (FIRST FIT) */
	m = (malloc_t *)g_heap_bot;
/* g_heap_bot == 0 == NULL if heap does not yet exist */
	if(m != NULL)
	{
		if(m->magic != MALLOC_MAGIC)
//			panic("kernel heap is corrupt in kmalloc()");
		{
			printf("*** kernel heap is corrupt in kmalloc()\n");
			return NULL;
		}
		for(; m->next != NULL; m = m->next)
		{
			if(m->used)
				continue;
/* size == m->size is a perfect fit */
			if(size == m->size)
				m->used = 1;
			else
			{
/* otherwise, we need an extra sizeof(malloc_t) bytes for the header
of a second, free block */
				if(total_size > m->size)
					continue;
/* create a new, smaller free block after this one */
				n = (malloc_t *)((char *)m + total_size);
				n->size = m->size - total_size;
				n->next = m->next;
				n->magic = MALLOC_MAGIC;
				n->used = 0;
/* reduce the size of this block and mark it used */
				m->size = size;
				m->next = n;
				m->used = 1;
			}
			return (char *)m + sizeof(malloc_t);
		}
	}
/* use kbrk() to enlarge (or create!) heap */
	delta = total_size;
	n = kbrk(&delta);
/* uh-oh */
	if(n == NULL)
		return NULL;
	if(m != NULL)
		m->next = n;
	n->size = size;
	n->magic = MALLOC_MAGIC;
	n->used = 1;
/* did kbrk() return the exact amount of memory we wanted?
cast to make "gcc -Wall -W ..." shut the hell up */
	if((int)total_size == delta)
		n->next = NULL;
	else
	{
/* it returned more than we wanted (it will never return less):
create a new, free block */
		m = (malloc_t *)((char *)n + total_size);
		m->size = delta - total_size - sizeof(malloc_t);
		m->next = NULL;
		m->magic = MALLOC_MAGIC;
		m->used = 0;

		n->next = m;
	}
	return (char *)n + sizeof(malloc_t);
}
Ejemplo n.º 3
0
static void *core_palloc(size_t size) {
  unsigned total_size;
  palloc_t *m, *n;
  int delta;

  if(size == 0)  return NULL;
  total_size = size + sizeof(palloc_t);

  /* search heap for free block (FIRST FIT) */
  m = (palloc_t *)p_heap_bottom;
  /* p_heap_bottom == 0 == NULL if heap does not yet exists */
  if(m != NULL) {
    for( ;m -> next != NULL; m = m -> next) {
      /* Check the heap nodes already allocated */
      if(check_magic(m) == FALSE) { 
				if(palloc_error_message(m) == TRUE)
					return NULL; 
			}

      if(m -> used) { 
        continue;  
      }
      /* size == m -> size is a perfect fit */
      if(size == m -> size) { m -> used = 1; }
      else {
        /* otherwise, we need an extra sizeof(palloc_t) bytes for the header
         * of a second, free block. */
        if(total_size > m -> size)  continue;

        /* create a new, smaller free block after this one. */
        n = (palloc_t *)((char *)m + total_size);
        n -> size = m -> size - total_size;
        n -> next = m -> next;
        n -> magic = PALLOC_MAGIC;
        /* An extra check to make sure all nodes allocated are proper */
        if(check_magic(m) == FALSE) { palloc_error_message(m); return NULL;  }
        n -> used = 0;
      
        /* reduce the size of this block and mark it used. */
        m -> size = size;
        m -> next = n;
        m -> used = 1;
      }
      /* return location of memory that is after palloc_t node (header) */
      return (char *)m + sizeof(palloc_t);
    }
  }
  /* Check the heap nodes already allocated */
  if(check_magic(m) == FALSE) {
    if(palloc_error_message(m) == TRUE)
	    return NULL;
  }
  /* use kbrk() to enlarge (or create!) heap */
  delta = total_size;
  n = kbrk(&delta);
    
  /* oops! allocation failed */
  if(n == NULL) return NULL;
  
  if(m != NULL) { m -> next = n; }

  n -> size = size;
  n -> magic = PALLOC_MAGIC;
  n -> used = 1;
  
  /* did kbrk() return exact amount of memory we wanted? */
  if((int) total_size == delta) n -> next = NULL;
  else {
    /* it returned more than we wanted (it will never return less)
     * create a new, free block. */
    m = (palloc_t *)((char *)n + total_size);
    m -> size = delta - total_size - sizeof(palloc_t);
    m -> next = NULL;
    m -> magic = PALLOC_MAGIC;
    m -> used = 0;

    n -> next = m;
  }
  /* return location of memory that is after palloc_t node (header) */
  return (char *) n + sizeof(palloc_t);
}