home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / pathalias2 / part2 / mem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  3.4 KB  |  201 lines

  1. /* pathalias -- by steve bellovin, as told to peter honeyman */
  2. #ifndef lint
  3. static char    *sccsid = "@(#)mem.c    8.1 (down!honey) 86/01/19";
  4. #endif
  5.  
  6. #include "def.h"
  7.  
  8. /* imported */
  9. extern char *sbrk();
  10.  
  11. link    *
  12. newlink()
  13. {
  14.     link    *rval;
  15.  
  16.     if ((rval = (link * ) calloc(1, sizeof(link))) == 0)
  17.         nomem();
  18.     return(rval);
  19. }
  20.  
  21. node    *
  22. newnode()
  23. {
  24.     node    *rval;
  25.  
  26.     if ((rval = (node * ) calloc(1, sizeof(node))) == 0)
  27.         nomem();
  28.     Ncount++;
  29.     return(rval);
  30. }
  31.  
  32. char    *
  33. strsave(s)
  34. char    *s;
  35. {
  36.     char *r;
  37.  
  38.     if ((r = malloc((unsigned int) strlen(s) + 1)) == 0)
  39.         nomem();
  40.     (void) strcpy(r, s);
  41.     return(r);
  42. }
  43.  
  44. #ifndef strclear
  45. void
  46. strclear(dst, len)
  47. register char *dst;
  48. register int len;
  49. {
  50.     while (--len >= 0)
  51.         *dst++ = 0;
  52. }
  53. #endif /*strclear*/
  54.  
  55. node    **
  56. newtable(size)
  57. long    size;
  58. {
  59.     node    **rval;
  60.  
  61.     if ((rval = (node **) calloc(1, (unsigned int) (size * sizeof(*rval)))) == 0) 
  62.         nomem();
  63.     return(rval);
  64. }
  65.  
  66. freetable(t, size)
  67. node    **t;
  68. long    size;
  69. {
  70. #ifdef MYMALLOC
  71.     addtoheap((char *) t, (long) (size * sizeof(*t)));
  72. #else
  73.     free((char *) t);
  74. #endif
  75. }
  76.  
  77. nomem()
  78. {
  79.     fprintf(stderr, "%s: Out of memory (%ldk allocated)\n",
  80.             ProgName, allocation());
  81.     badmagic(1);
  82. }
  83.  
  84. /* data space allocation -- main sets End very early */
  85. allocation()
  86. {
  87.     static char    *dataspace;
  88.  
  89.     if (dataspace == 0) {    /* first time */
  90.         dataspace = sbrk(0);        /* &end? */
  91.         return(0);
  92.     }
  93.     return((sbrk(0) - dataspace)/1024);
  94. }
  95.  
  96. #ifdef MYMALLOC
  97.  
  98. /* use c library malloc/calloc here, and here only */
  99. #undef malloc
  100. #undef calloc
  101. extern char *malloc(), *calloc();
  102.  
  103. /* allocate in MBUFSIZ chunks.  4k works ok (less 16 for malloc quirks). */
  104. #define MBUFSIZ (4 * 1024 - 16)
  105.  
  106. /* 
  107.  * mess with ALIGN at your peril.  longword (== 0 mod 4)
  108.  * alignment seems to work everywhere.
  109.  */
  110.  
  111. #define ALIGN 2
  112.  
  113. typedef struct heap heap;
  114. struct heap {
  115.     heap *h_next;
  116.     long h_size;
  117. };
  118.  
  119. static heap *Mheap;    /* not to be confused with a priority queue */
  120.  
  121. addtoheap(p, size)
  122. char *p;
  123. long size;
  124. {
  125.     int adjustment;
  126.     heap *pheap;
  127.  
  128.     /* p is aligned, but it doesn't hurt to check */
  129.     adjustment = align(p);
  130.     p += adjustment;
  131.     size -= adjustment;
  132.  
  133.     if (size < 1024)
  134.         return;        /* can't happen */
  135.     pheap = (heap *) p;    /* pheap is shorthand */
  136.     pheap->h_next = Mheap;
  137.     pheap->h_size = size;
  138.     Mheap = pheap;
  139. }
  140.  
  141. /*
  142.  * buffered malloc()
  143.  *    returns space initialized to 0.  calloc isn't used, since
  144.  *    strclear can be faster.
  145.  *
  146.  * free is ignored, except for very large objects,
  147.  * which are returned to the heap with addtoheap(). 
  148.  */
  149.  
  150. char    *
  151. mymalloc(n)
  152. register unsigned int    n;
  153. {
  154.     static long    size;        /* how much do we have on hand? */
  155.     static char    *mstash;    /* where is it?  (kept aligned) */
  156.     register char    *rval;
  157.  
  158.     n += align((char *) n);    /* keep everything aligned */
  159.     if (n >= 1024) {        /* from hash table */
  160.         rval = malloc(n);    /* aligned */
  161.         strclear(rval, n);
  162.         return(rval);
  163.     }
  164.     
  165.  
  166.     if (n > size) {
  167.         /* look in the heap (already aligned) */
  168.         if (Mheap) {
  169.             mstash = (char *) Mheap;
  170.             size = Mheap->h_size;
  171.             Mheap = Mheap->h_next;
  172.         } else {
  173.             mstash = malloc(MBUFSIZ);    /* aligned */
  174.             if (mstash == 0) {
  175.                 size = 0;
  176.                 return(0);
  177.             }
  178.             size = MBUFSIZ;
  179.         }
  180.         strclear(mstash, size);
  181.     }
  182.     rval = mstash;
  183.     mstash += n;
  184.     size -= n;
  185.     return(rval);
  186. }
  187.  
  188. /* what's the (mis-)alignment of n?  return the complement of (n mod 2^ALIGN) */
  189. align(n)
  190. char    *n;
  191. {
  192.     int    abits;    /* misalignment bits in n */
  193.  
  194.     abits = (int) n & ~(0xff << ALIGN) & 0xff;
  195.     if (abits == 0)
  196.         return(0);
  197.     return((1 << ALIGN) - abits);
  198. }
  199.  
  200. #endif /*MYMALLOC*/
  201.