Skip to content
Snippets Groups Projects
umalloc.c 1.63 KiB
Newer Older
kaashoek's avatar
kaashoek committed
#include "types.h"
#include "stat.h"
#include "user.h"
#include "param.h"

rsc's avatar
rsc committed
// Memory allocator by Kernighan and Ritchie, The C programming Language,
kaashoek's avatar
kaashoek committed
// 2nd ed.  Section 8.7.

typedef long Align;

union header {
  struct {
    union header *ptr;
    uint size;
  } s;
  Align x;
};

typedef union header Header;

static Header base;
static Header *freep = 0;

void
free(void *ap)
{
  Header *bp, *p;
kaashoek's avatar
kaashoek committed

rsc's avatar
rsc committed
  bp = (Header*) ap - 1;
  for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
    if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))
kaashoek's avatar
kaashoek committed
      break;
rsc's avatar
rsc committed
  if(bp + bp->s.size == p->s.ptr) {
kaashoek's avatar
kaashoek committed
    bp->s.size += p->s.ptr->s.size;
    bp->s.ptr = p->s.ptr->s.ptr;
  } else
    bp->s.ptr = p->s.ptr;
rsc's avatar
rsc committed
  if(p + p->s.size == bp) {
kaashoek's avatar
kaashoek committed
    p->s.size += bp->s.size;
    p->s.ptr = bp->s.ptr;
  } else
    p->s.ptr = bp;
  freep = p;
}

rsc's avatar
rsc committed
static Header*
kaashoek's avatar
kaashoek committed
morecore(uint nu)
{
  char *cp;
  Header *up;
rsc's avatar
rsc committed

  if(nu < PAGE)
kaashoek's avatar
kaashoek committed
    nu = PAGE;
  cp = sbrk(nu * sizeof(Header));
rsc's avatar
rsc committed
  if(cp == (char*) -1)
kaashoek's avatar
kaashoek committed
    return 0;
rsc's avatar
rsc committed
  up = (Header*) cp;
kaashoek's avatar
kaashoek committed
  up->s.size = nu;
rsc's avatar
rsc committed
  free((void*)(up + 1));
kaashoek's avatar
kaashoek committed
  return freep;
}

rsc's avatar
rsc committed
void*
kaashoek's avatar
kaashoek committed
malloc(uint nbytes)
{
  Header *p, *prevp;
  uint nunits;

  nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
rsc's avatar
rsc committed
  if((prevp = freep) == 0) {
kaashoek's avatar
kaashoek committed
    base.s.ptr = freep = prevp = &base;
    base.s.size = 0;
  }
rsc's avatar
rsc committed
  for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
    if(p->s.size >= nunits) {
      if(p->s.size == nunits)
        prevp->s.ptr = p->s.ptr;
kaashoek's avatar
kaashoek committed
      else {
        p->s.size -= nunits;
        p += p->s.size;
        p->s.size = nunits;
kaashoek's avatar
kaashoek committed
      }
      freep = prevp;
rsc's avatar
rsc committed
      return (void*) (p + 1);
kaashoek's avatar
kaashoek committed
    }
rsc's avatar
rsc committed
    if(p == freep)
      if((p = morecore(nunits)) == 0)