umalloc.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "types.h"
  2. #include "stat.h"
  3. #include "user.h"
  4. #include "param.h"
  5. // Memory allocator by Kernighan and Ritchie,
  6. // The C programming Language, 2nd ed. Section 8.7.
  7. typedef long Align;
  8. union header {
  9. struct {
  10. union header *ptr;
  11. uint size;
  12. } s;
  13. Align x;
  14. };
  15. typedef union header Header;
  16. static Header base;
  17. static Header *freep;
  18. void
  19. free(void *ap)
  20. {
  21. Header *bp, *p;
  22. bp = (Header*)ap - 1;
  23. for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
  24. if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))
  25. break;
  26. if(bp + bp->s.size == p->s.ptr){
  27. bp->s.size += p->s.ptr->s.size;
  28. bp->s.ptr = p->s.ptr->s.ptr;
  29. } else
  30. bp->s.ptr = p->s.ptr;
  31. if(p + p->s.size == bp){
  32. p->s.size += bp->s.size;
  33. p->s.ptr = bp->s.ptr;
  34. } else
  35. p->s.ptr = bp;
  36. freep = p;
  37. }
  38. static Header*
  39. morecore(uint nu)
  40. {
  41. char *p;
  42. Header *hp;
  43. if(nu < 4096)
  44. nu = 4096;
  45. p = sbrk(nu * sizeof(Header));
  46. if(p == (char*)-1)
  47. return 0;
  48. hp = (Header*)p;
  49. hp->s.size = nu;
  50. free((void*)(hp + 1));
  51. return freep;
  52. }
  53. void*
  54. malloc(uint nbytes)
  55. {
  56. Header *p, *prevp;
  57. uint nunits;
  58. nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
  59. if((prevp = freep) == 0){
  60. base.s.ptr = freep = prevp = &base;
  61. base.s.size = 0;
  62. }
  63. for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){
  64. if(p->s.size >= nunits){
  65. if(p->s.size == nunits)
  66. prevp->s.ptr = p->s.ptr;
  67. else {
  68. p->s.size -= nunits;
  69. p += p->s.size;
  70. p->s.size = nunits;
  71. }
  72. freep = prevp;
  73. return (void*)(p + 1);
  74. }
  75. if(p == freep)
  76. if((p = morecore(nunits)) == 0)
  77. return 0;
  78. }
  79. }