Xmalloc.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /* M E M O R Y A L L O C A T I O N R O U T I N E S */
  2. /* The reason for having own memory allocation routines (malloc(),
  3. realloc() and free()) is plain: the garbage collection performed by
  4. the library functions malloc(), realloc() and free() costs a lot of
  5. time, while in most cases (on a VAX) the freeing and reallocation of
  6. memory is not necessary.
  7. The (basic) memory allocating routines offered by this memory
  8. handling package are:
  9. char *malloc(n) : allocate n bytes
  10. char *realloc(ptr, n) : reallocate buffer to n bytes
  11. (works only if ptr was last allocated)
  12. free(ptr) : if ptr points to last allocated
  13. memory, this memory is re-allocatable
  14. This module imports routines from "system", an assertion macro,
  15. and the compile-time
  16. constants ALIGNBITS, ALLOCSIZ, DEBUG.
  17. ALIGNBITS is an integer constant defining suitable alignment,
  18. ALLOCSIZ is the size of the chunks of memory asked from the system,
  19. DEBUG enables the assertions.
  20. */
  21. #include <assert.h>
  22. #include <system.h>
  23. #ifndef ALIGNBITS
  24. #define ALIGNBITS 07
  25. #endif
  26. #ifndef ALLOCSIZ
  27. #define ALLOCSIZ 4096
  28. #endif
  29. /* the following variables are used for book-keeping */
  30. static int nfreebytes = 0; /* # free bytes in sys_break-ed space */
  31. static char *freeb = 0; /* pointer to first free byte */
  32. static char *lastalloc; /* pointer to last malloced sp */
  33. static int lastnbytes; /* nr of bytes in last allocated space */
  34. static char *firstfreeb; /* pointer to first ever free byte */
  35. #define ALIGN(m) (((m)&ALIGNBITS)? (m)+((1+ALIGNBITS)-((m)&ALIGNBITS)):(m))
  36. char *sys_break();
  37. char *
  38. malloc(n)
  39. unsigned int n;
  40. {
  41. /* malloc() is a very simple malloc().
  42. */
  43. n = ALIGN(n);
  44. if (nfreebytes < n) {
  45. register int nbts = (n <= ALLOCSIZ) ? ALLOCSIZ : n;
  46. if (!nfreebytes) {
  47. if (!firstfreeb) {
  48. /* We arrive here the first time malloc is
  49. called
  50. */
  51. int diff;
  52. if (!(freeb = sys_break(0))) return 0;
  53. if ((diff = (int)((long)freeb&ALIGNBITS))!=0) {
  54. /* align memory to ALIGNBITS ... */
  55. diff = (1 + ALIGNBITS) - diff;
  56. if (!(freeb = sys_break(diff))) {
  57. return 0;
  58. }
  59. freeb += diff;
  60. assert(((long)freeb & ALIGNBITS) == 0);
  61. }
  62. firstfreeb = freeb;
  63. }
  64. if (!(freeb = sys_break(nbts))) return 0;
  65. }
  66. else {
  67. if (!sys_break(nbts)) return 0;
  68. }
  69. nfreebytes += nbts;
  70. }
  71. lastalloc = freeb;
  72. freeb = lastalloc + n;
  73. lastnbytes = n;
  74. nfreebytes -= n;
  75. return lastalloc;
  76. }
  77. char *
  78. realloc(ptr, n)
  79. char *ptr;
  80. unsigned int n;
  81. {
  82. /* realloc() is designed to append more bytes to the latest
  83. allocated piece of memory.
  84. */
  85. register int nbytes = n;
  86. if (!ptr || ptr != lastalloc) { /* security */
  87. return 0;
  88. }
  89. nbytes -= lastnbytes; /* # bytes required */
  90. if (nbytes == 0) { /* no extra bytes */
  91. return lastalloc;
  92. }
  93. /* if nbytes < 0: free last allocated bytes;
  94. if nbytes > 0: allocate more bytes
  95. */
  96. if (nbytes > 0) nbytes = ALIGN(nbytes);
  97. if (nfreebytes < nbytes) {
  98. register int nbts = (nbytes < ALLOCSIZ) ? ALLOCSIZ : nbytes;
  99. if (!sys_break(nbts)) return 0;
  100. nfreebytes += nbts;
  101. }
  102. freeb += nbytes; /* less bytes */
  103. lastnbytes += nbytes; /* change nr of last all. bytes */
  104. nfreebytes -= nbytes; /* less or more free bytes */
  105. return lastalloc;
  106. }
  107. free(p)
  108. char *p;
  109. {
  110. if (lastalloc && lastalloc == p) {
  111. nfreebytes += lastnbytes;
  112. freeb = lastalloc;
  113. lastnbytes = 0;
  114. lastalloc = 0;
  115. }
  116. }
  117. #ifdef DEBUG
  118. mem_stat()
  119. {
  120. printf("Total nr of bytes allocated: %d\n",
  121. sys_break(0) - firstfreeb);
  122. }
  123. #endif DEBUG