asscm.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. */
  6. /* Core management for the EM assembler.
  7. two routines:
  8. getarea(size)
  9. returns a pointer to a free area of 'size' bytes.
  10. freearea(ptr,size)
  11. free's the area of 'size' bytes pointed to by ptr
  12. Free blocks are linked together and kept sorted.
  13. Adjacent free blocks are collapsed.
  14. Free blocks with a size smaller then the administration cannot
  15. exist.
  16. The algorithm is first fit.
  17. */
  18. #include "ass00.h"
  19. #ifndef NORCSID
  20. static char rcs_id[] = "$Id$" ;
  21. #endif
  22. #ifdef MEMUSE
  23. static unsigned m_used = 0 ;
  24. static unsigned m_free = 0 ;
  25. #endif
  26. struct freeblock {
  27. struct freeblock *f_next ;
  28. unsigned f_size ;
  29. } ;
  30. static struct freeblock freexx[2] = {
  31. { freexx, 0 },
  32. { freexx+1, 0 }
  33. } ;
  34. #define freehead freexx[1]
  35. #define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */
  36. area_t getarea(size) unsigned size ; {
  37. register struct freeblock *c_ptr,*l_ptr ;
  38. register char *ptr ;
  39. unsigned rqsize ;
  40. char *malloc() ;
  41. size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
  42. #ifdef MEMUSE
  43. m_used += size ;
  44. m_free -= size ;
  45. #endif
  46. for(;;) {
  47. for ( l_ptr= &freehead, c_ptr= freehead.f_next ;
  48. c_ptr!= &freehead ; c_ptr = c_ptr->f_next ) {
  49. if ( size==c_ptr->f_size ) {
  50. l_ptr->f_next= c_ptr->f_next ;
  51. return (area_t) c_ptr ;
  52. }
  53. if ( size+sizeof freehead <= c_ptr->f_size ) {
  54. c_ptr->f_size -= size ;
  55. return (area_t) ((char *) c_ptr + c_ptr->f_size) ;
  56. }
  57. l_ptr = c_ptr ;
  58. }
  59. rqsize = size<CHUNK ? CHUNK : size ;
  60. for(;;){
  61. ptr = malloc( rqsize ) ;
  62. if ( ptr ) break ; /* request succesfull */
  63. rqsize /= 2 ;
  64. rqsize -= rqsize%sizeof (int) ;
  65. if ( rqsize < sizeof freehead ) {
  66. fatal("Out of memory") ;
  67. }
  68. }
  69. freearea((area_t)ptr,rqsize) ;
  70. #ifdef MEMUSE
  71. m_used += rqsize ;
  72. #endif
  73. }
  74. /* NOTREACHED */
  75. }
  76. freearea(ptr,size) register area_t ptr ; unsigned size ; {
  77. register struct freeblock *c_ptr, *l_ptr ;
  78. size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
  79. #ifdef MEMUSE
  80. m_free += size ;
  81. m_used -= size ;
  82. #endif
  83. for ( l_ptr= &freehead, c_ptr=freehead.f_next ;
  84. c_ptr!= &freehead ; c_ptr= c_ptr->f_next ) {
  85. if ( (area_t)c_ptr>ptr ) break ;
  86. l_ptr= c_ptr ;
  87. }
  88. /* now insert between l_ptr and c_ptr */
  89. /* Beware they may both point to freehead */
  90. #ifdef MEMUSE
  91. if ( ((char *)l_ptr)+l_ptr->f_size> (char *)ptr && (char *)l_ptr<=(char *)ptr )
  92. fatal("Double freed") ;
  93. if ( ((char *)ptr)+size > (char *)c_ptr && (char *)ptr<=(char *)c_ptr )
  94. fatal("Frreed double") ;
  95. #endif
  96. /* Is the block before this one adjacent ? */
  97. if ( ((char *)l_ptr) + l_ptr->f_size == (char *) ptr ) {
  98. l_ptr->f_size += size ; /* yes */
  99. } else {
  100. /* No, create an entry */
  101. ((struct freeblock *)ptr)->f_next = c_ptr ;
  102. ((struct freeblock *)ptr)->f_size = size ;
  103. l_ptr->f_next = (struct freeblock *)ptr ;
  104. l_ptr = (struct freeblock *)ptr ;
  105. }
  106. /* Are the two entries adjacent ? */
  107. if ( (char *)l_ptr + l_ptr->f_size == (char *) c_ptr ) {
  108. /* the two entries are adjacent */
  109. l_ptr->f_next = c_ptr->f_next ;
  110. l_ptr->f_size += c_ptr->f_size ;
  111. }
  112. }
  113. #ifdef MEMUSE
  114. memuse() {
  115. printf("Free %7u, Used %7u, Total %7u\n",m_free,m_used,m_free+m_used);
  116. }
  117. #endif