xv6-65oo2/user/umalloc.c

91 lines
1.6 KiB
C
Raw Permalink Normal View History

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/param.h"
2007-08-27 23:26:33 +00:00
// Memory allocator by Kernighan and Ritchie,
// The C programming Language, 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;
2007-08-10 17:17:42 +00:00
static Header *freep;
void
free(void *ap)
{
Header *bp, *p;
2006-08-24 19:24:36 +00:00
bp = (Header*)ap - 1;
2006-09-06 17:27:19 +00:00
for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))
break;
2007-08-28 18:32:08 +00:00
if(bp + bp->s.size == p->s.ptr){
bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
2007-08-28 18:37:41 +00:00
} else
bp->s.ptr = p->s.ptr;
2007-08-28 18:32:08 +00:00
if(p + p->s.size == bp){
p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
2007-08-28 18:37:41 +00:00
} else
p->s.ptr = bp;
freep = p;
}
2006-09-06 17:27:19 +00:00
static Header*
morecore(uint nu)
{
2007-08-09 17:32:40 +00:00
char *p;
Header *hp;
2006-09-06 17:27:19 +00:00
if(nu < 4096)
nu = 4096;
2007-08-09 17:32:40 +00:00
p = sbrk(nu * sizeof(Header));
if(p == (char*)-1)
return 0;
2007-08-09 17:32:40 +00:00
hp = (Header*)p;
hp->s.size = nu;
free((void*)(hp + 1));
return freep;
}
2006-09-06 17:27:19 +00:00
void*
malloc(uint nbytes)
{
Header *p, *prevp;
uint nunits;
nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
2007-08-28 18:32:08 +00:00
if((prevp = freep) == 0){
base.s.ptr = freep = prevp = &base;
base.s.size = 0;
}
2007-08-28 18:32:08 +00:00
for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){
if(p->s.size >= nunits){
2006-09-06 17:27:19 +00:00
if(p->s.size == nunits)
prevp->s.ptr = p->s.ptr;
2007-08-28 18:37:41 +00:00
else {
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void*)(p + 1);
}
2006-09-06 17:27:19 +00:00
if(p == freep)
if((p = morecore(nunits)) == 0)
return 0;
}
}