dis.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. *
  5. * This product is part of the Amsterdam Compiler Kit.
  6. *
  7. * Permission to use, sell, duplicate or disclose this software must be
  8. * obtained in writing. Requests for such permissions may be sent to
  9. *
  10. * Dr. Andrew S. Tanenbaum
  11. * Wiskundig Seminarium
  12. * Vrije Universiteit
  13. * Postbox 7161
  14. * 1007 MC Amsterdam
  15. * The Netherlands
  16. *
  17. */
  18. /* Author: J.W. Stevenson */
  19. #include <pc_err.h>
  20. #define assert() /* nothing */
  21. /*
  22. * use circular list of free blocks from low to high addresses
  23. * _highp points to free block with highest address
  24. */
  25. struct adm {
  26. struct adm *next;
  27. int size;
  28. };
  29. extern struct adm *_lastp;
  30. extern struct adm *_highp;
  31. extern _trp();
  32. static int merge(p1,p2) struct adm *p1,*p2; {
  33. struct adm *p;
  34. p = (struct adm *)((char *)p1 + p1->size);
  35. if (p > p2)
  36. _trp(EFREE);
  37. if (p != p2)
  38. return(0);
  39. p1->size += p2->size;
  40. p1->next = p2->next;
  41. return(1);
  42. }
  43. _dis(n,pp) int n; struct adm **pp; {
  44. struct adm *p1,*p2;
  45. /*
  46. * NOTE: dispose only objects whose size is a multiple of sizeof(*pp).
  47. * this is always true for objects allocated by _new()
  48. */
  49. n = ((n+sizeof(*p1)-1) / sizeof(*p1)) * sizeof(*p1);
  50. if (n == 0)
  51. return;
  52. if ((p1= *pp) == (struct adm *) 0)
  53. _trp(EFREE);
  54. p1->size = n;
  55. if ((p2 = _highp) == 0) /*p1 is the only free block*/
  56. p1->next = p1;
  57. else {
  58. if (p2 > p1) {
  59. /*search for the preceding free block*/
  60. if (_lastp < p1) /*reduce search*/
  61. p2 = _lastp;
  62. while (p2->next < p1)
  63. p2 = p2->next;
  64. }
  65. /* if p2 preceeds p1 in the circular list,
  66. * try to merge them */
  67. p1->next = p2->next; p2->next = p1;
  68. if (p2 <= p1 && merge(p2,p1))
  69. p1 = p2;
  70. p2 = p1->next;
  71. /* p1 preceeds p2 in the circular list */
  72. if (p2 > p1) merge(p1,p2);
  73. }
  74. if (p1 >= p1->next)
  75. _highp = p1;
  76. _lastp = p1;
  77. *pp = (struct adm *) 0;
  78. }