home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / code / microema.sit / src / malloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-09  |  3.0 KB  |  159 lines  |  [TEXT/Earl]

  1. /*
  2.  * Sensible malloc and free() for use with microemacs for the Mac.
  3.  *
  4.  * Source:  These routines are for the most part adaptations of 
  5.  *    the storage allocator example program from pages 173-177
  6.  *    of "The C Programming Language" by Brian Kernighan and
  7.  *    Dennis M. Ritchie, Prentice-Hall Software Series, 1978
  8.  *
  9.  * These routines do somewhat more than memory allocation, too.
  10.  * In this module I attempt to limit the amount of memory malloced,
  11.  * and to reserve a minimum amount of memory for the operating
  12.  * system to use.  NOTE: the memory reserved to the operating system
  13.  * contains the actual code of the program, among other things!
  14.  */
  15.  
  16. #define MICROEMACS
  17.  
  18. #ifdef MICROEMACS
  19. extern long envram;
  20. #endif
  21.  
  22. #ifndef macintosh    /* MPW */
  23. #ifndef MPU68000    /* Aztec */
  24. #define LSC        /* Yuch! */
  25. #endif
  26. #endif
  27.  
  28. extern long malloc_safety;
  29.  
  30. #ifdef LSC
  31. #define FreeMem xxFreeMem
  32. #define NewPtr xxNewPtr
  33. long FreeMem()
  34. {
  35.     asm{
  36.         dc.w 0xA01C
  37.     }
  38. }
  39. char *NewPtr(size)
  40. long size;
  41. {
  42.     asm{
  43.         move.l    size,d0
  44.         dc.w    0xA11E
  45.         move.l    a0,d0
  46.     }
  47. }
  48. #else
  49. long FreeMem();
  50. char *NewPtr();
  51. #include <Strings.h>
  52. #endif
  53.  
  54. #ifndef NULL
  55. #define NULL 0L
  56. #endif
  57.  
  58. typedef long ALIGN;
  59. union header{
  60.     struct{
  61.         union header *ptr;
  62.         long size;
  63.     } s;
  64.     ALIGN    x;
  65. };
  66. typedef union header HEADER;
  67.  
  68. static HEADER base;
  69. static HEADER *allocp  = NULL;
  70.  
  71. #define NALLOC 128L
  72. static HEADER *morecore(nu)
  73. unsigned long nu;
  74. {
  75.     char *sbrk();
  76.     register char *cp;
  77.     register HEADER *up;
  78.     register long rnu;
  79.     register long s;
  80.     
  81.     rnu = NALLOC * ((nu+NALLOC-1L)/NALLOC);
  82.     if (FreeMem() < malloc_safety) return NULL;
  83.     cp = NewPtr(rnu*(long)sizeof(HEADER));
  84. #ifdef MICROEMACS
  85.     envram += rnu*(long)sizeof(HEADER);
  86. #endif
  87.     if(cp == NULL) return NULL;
  88.     up = (HEADER *)cp;
  89.     up->s.size = rnu;
  90.     free((char *)(up + 1));
  91.     return(allocp);
  92. }
  93.  
  94. #ifndef macintosh        /* MPW C uses long ints, others use short ones. */
  95. char *malloc(nbytes)
  96. unsigned int nbytes;
  97. {
  98.     char *lmalloc();
  99.     return lmalloc((long)nbytes);
  100. }
  101. char *lmalloc(nbytes)
  102. #else
  103. char *malloc(nbytes)
  104. #endif
  105. unsigned long nbytes;
  106. {
  107.     HEADER *morecore();
  108.     register HEADER *p,*q;
  109.     register long nunits;
  110.     
  111.     nunits = 1L+(nbytes+(long)sizeof(HEADER)-1L)/(long)sizeof(HEADER);
  112.     if ((q = allocp) == NULL){
  113.         base.s.ptr = allocp = q = &base;
  114.         base.s.size = 0;
  115.     }
  116.     for(p = q->s.ptr; ;q=p, p=p->s.ptr){
  117.         if(p->s.size >= nunits){
  118.             if(p->s.size == nunits)
  119.                 q->s.ptr = p->s.ptr;
  120.             else{
  121.                 p->s.size -= nunits;
  122.                 p += p->s.size;
  123.                 p->s.size = nunits;
  124.             }
  125.             allocp = q;
  126.             return((char *)(p + 1));
  127.         }
  128.         if (p == allocp)
  129.             if ((p = morecore(nunits))==NULL){
  130.                 return(NULL);
  131.             }
  132.     }
  133. }
  134. free(ap)
  135. char *ap;
  136. {
  137.     register HEADER *p,*q;
  138.     if(ap == NULL){        /* Manifest programmer error. */
  139.         return;
  140.     }
  141.     p = (HEADER *)ap - 1;
  142.     for (q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr)
  143.         if (q >= q->s.ptr && (p > q || p < q->s.ptr))
  144.             break;
  145.     if (p + p->s.size == q->s.ptr){
  146.         p->s.size += q->s.ptr->s.size;
  147.         p->s.ptr = q->s.ptr->s.ptr;
  148.     }
  149.     else
  150.         p->s.ptr = q->s.ptr;
  151.     if (q + q->s.size == p){
  152.         q->s.size += p->s.size;
  153.         q->s.ptr = p->s.ptr;
  154.     }
  155.     else
  156.         q->s.ptr = p;
  157.     allocp = q;
  158. }
  159.