user/umalloc.c
90 lines
1#include "kernel/types.h"2#include "kernel/stat.h"3#include "user/user.h"4#include "kernel/param.h"56// Memory allocator by Kernighan and Ritchie,7// The C programming Language, 2nd ed. Section 8.7.89typedef long Align;1011union header {12 struct {13 union header *ptr;14 uint size;15 } s;16 Align x;17};1819typedef union header Header;2021static Header base;22static Header *freep;2324void25free(void *ap)26{27 Header *bp, *p;2829 bp = (Header*)ap - 1;30 for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)31 if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))32 break;33 if(bp + bp->s.size == p->s.ptr){34 bp->s.size += p->s.ptr->s.size;35 bp->s.ptr = p->s.ptr->s.ptr;36 } else37 bp->s.ptr = p->s.ptr;38 if(p + p->s.size == bp){39 p->s.size += bp->s.size;40 p->s.ptr = bp->s.ptr;41 } else42 p->s.ptr = bp;43 freep = p;44}4546static Header*47morecore(uint nu)48{49 char *p;50 Header *hp;5152 if(nu < 4096)53 nu = 4096;54 p = sbrk(nu * sizeof(Header));55 if(p == SBRK_ERROR)56 return 0;57 hp = (Header*)p;58 hp->s.size = nu;59 free((void*)(hp + 1));60 return freep;61}6263void*64malloc(uint nbytes)65{66 Header *p, *prevp;67 uint nunits;6869 nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;70 if((prevp = freep) == 0){71 base.s.ptr = freep = prevp = &base;72 base.s.size = 0;73 }74 for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){75 if(p->s.size >= nunits){76 if(p->s.size == nunits)77 prevp->s.ptr = p->s.ptr;78 else {79 p->s.size -= nunits;80 p += p->s.size;81 p->s.size = nunits;82 }83 freep = prevp;84 return (void*)(p + 1);85 }86 if(p == freep)87 if((p = morecore(nunits)) == 0)88 return 0;89 }90}91