《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
3.6 KiB

  1. #include <stdio.h>
  2. //K&R Chapt5, Section 4
  3. #if 0
  4. #define ALLOCSIZE 10000
  5. static char allocbuf[ALLOCSIZE]; /*storage for alloc*/
  6. static char *allocp = allocbuf; /*next free position*/
  7. char *alloc(int n)
  8. {
  9. if(allocbuf+ALLOCSIZE - allocp >= n) {
  10. allocp += n;
  11. return alloc - n;
  12. } else
  13. return 0;
  14. }
  15. void afree(char *p)
  16. {
  17. if (p >= allocbuf && p<allocbuf + ALLOCSIZE)
  18. allocp = p;
  19. }
  20. #endif
  21. //K&R Chapt8, Section 7
  22. #define NULL 0
  23. typedef long Align;/*for alignment to long boundary*/
  24. union header {
  25. struct {
  26. union header *ptr; /*next block if on free list*/
  27. unsigned size; /*size of this block*/
  28. } s;
  29. Align x;
  30. };
  31. typedef union header Header;
  32. static Header base;
  33. static Header *freep = NULL;
  34. void kr_free(void *ap)
  35. {
  36. Header *bp,*p;
  37. bp = (Header *)ap -1; /* point to block header */
  38. printf("kr_free: bp 0x%x, size %d\n",bp,bp->s.size);
  39. for(p=freep;!(bp>p && bp< p->s.ptr);p=p->s.ptr)
  40. if(p>=p->s.ptr && (bp>p || bp<p->s.ptr))
  41. break; /* freed block at start or end of arena*/
  42. if (bp+bp->s.size==p->s.ptr) { /* join to upper nbr */
  43. bp->s.size += p->s.ptr->s.size;
  44. bp->s.ptr = p->s.ptr->s.ptr;
  45. } else
  46. bp->s.ptr = p->s.ptr;
  47. if (p+p->s.size == bp) { /* join to lower nbr */
  48. p->s.size += bp->s.size;
  49. p->s.ptr = bp->s.ptr;
  50. } else
  51. p->s.ptr = bp;
  52. freep = p;
  53. }
  54. #define NALLOC 1024 /* minimum #units to request */
  55. static Header *morecore(unsigned nu)
  56. {
  57. char *cp;
  58. Header *up;
  59. if(nu < NALLOC)
  60. nu = NALLOC;
  61. cp = sbrk(nu * sizeof(Header));
  62. printf("morecore: cp 0x%x, size %d\n",cp,nu * sizeof(Header));
  63. if(cp == (char *)-1) /* no space at all*/
  64. return NULL;
  65. up = (Header *)cp;
  66. up->s.size = nu;
  67. kr_free((void *)(up+1));
  68. return freep;
  69. }
  70. void *kr_malloc(unsigned nbytes)
  71. {
  72. Header *p, *prevp;
  73. unsigned nunits;
  74. nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1;
  75. printf("kr_malloc: nbytes %d, nunits %d\n",nbytes,nunits);
  76. if((prevp = freep) == NULL) { /* no free list */
  77. base.s.ptr = freep = prevp = &base;
  78. base.s.size = 0;
  79. }
  80. for(p = prevp->s.ptr; ;prevp = p, p= p->s.ptr) {
  81. if(p->s.size >= nunits) { /* big enough */
  82. if (p->s.size == nunits) /* exactly */
  83. prevp->s.ptr = p->s.ptr;
  84. else {
  85. p->s.size -= nunits;
  86. p += p->s.size;
  87. p->s.size = nunits;
  88. }
  89. freep = prevp;
  90. printf("kr_malloc: p 0x%x, size %d\n",p,p->s.size);
  91. return (void*)(p+1);
  92. }
  93. if (p== freep) /* wrapped around free list */
  94. if ((p = morecore(nunits)) == NULL) {
  95. printf("kr_malloc: no free space!!!\n");
  96. return NULL; /* none left */
  97. }
  98. }
  99. }
  100. void kr_dump(void)
  101. { static int i=0;
  102. Header *p, *prevp;
  103. prevp = freep;
  104. i++;
  105. for(p = prevp->s.ptr; ;prevp = p, p= p->s.ptr) {
  106. if(p== freep) {
  107. return;
  108. }
  109. printf("kr_dump: %d: p 0x%x, size %d\n", i, p, p->s.size);
  110. }
  111. }
  112. void main(void)
  113. {
  114. void * na,*nb,*nc,*nd,*ne, *nf;
  115. printf("size of Header is %d\n", sizeof(Header));
  116. na=kr_malloc(16);
  117. kr_dump();
  118. kr_free(na);
  119. kr_dump();
  120. nb=kr_malloc(48);
  121. kr_dump();
  122. nc=kr_malloc(60);
  123. kr_dump();
  124. nd=kr_malloc(128);
  125. kr_dump();
  126. kr_free(nb);
  127. kr_dump();
  128. ne=kr_malloc(512);
  129. kr_dump();
  130. kr_free(nd);
  131. kr_dump();
  132. nf=kr_malloc(256);
  133. kr_dump();
  134. kr_free(nc);
  135. kr_dump();
  136. kr_free(nf);
  137. kr_dump();
  138. kr_free(ne);
  139. kr_dump();
  140. }