home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / auucp+-1.02 / fuucp_plus_src.lzh / pathalias / mem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-17  |  4.4 KB  |  254 lines

  1. /* pathalias -- by steve bellovin, as told to peter honeyman */
  2. #ifndef lint
  3. static char    *sccsid = "@(#)mem.c    9.2 88/06/10";
  4. #endif
  5.  
  6. #include "def.h"
  7.  
  8. /* exports */
  9. long Ncount;
  10. extern void freelink(), wasted(), freetable();
  11. extern long allocation();
  12.  
  13. /* imports */
  14. extern char *Netchars;
  15. extern int Vflag;
  16. extern char *sbrk();
  17. extern void die();
  18. extern int strlen();
  19.  
  20. /* privates */
  21. STATIC void nomem();
  22. static link *Lcache;
  23. static unsigned int Memwaste;
  24.  
  25. link    *
  26. newlink()
  27. {    register link *rval;
  28.  
  29.     if (Lcache) {
  30.          rval = Lcache;
  31.         Lcache = Lcache->l_next;
  32.         strclear((char *) rval, sizeof(link));
  33.     } else if ((rval = (link * ) calloc(1, sizeof(link))) == 0)
  34.         nomem();
  35.     return rval;
  36. }
  37.  
  38. /* caution: this destroys the contents of l_next */
  39. void
  40. freelink(l)
  41.     link *l;
  42. {
  43.     l->l_next = Lcache;
  44.     Lcache = l;
  45. }
  46.  
  47. node    *
  48. newnode()
  49. {    register node *rval;
  50.  
  51.     if ((rval = (node * ) calloc(1, sizeof(node))) == 0)
  52.         nomem();
  53.     Ncount++;
  54.     return rval;
  55. }
  56.  
  57. char    *
  58. strsave(s)
  59.     char *s;
  60. {    register char *r;
  61.  
  62.     if ((r = malloc((unsigned) strlen(s) + 1)) == 0)
  63.         nomem();
  64.     (void) strcpy(r, s);
  65.     return r;
  66. }
  67.  
  68. #ifndef strclear
  69. void
  70. strclear(str, len)
  71.     register char *str;
  72.     register long len;
  73. {
  74.     while (--len >= 0)
  75.         *str++ = 0;
  76. }
  77. #endif /*strclear*/
  78.  
  79. node    **
  80. newtable(size)
  81.     long size;
  82. {    register node **rval;
  83.  
  84.     if ((rval = (node **) calloc(1, (unsigned int) size * sizeof(node *))) == 0) 
  85.         nomem();
  86.     return rval;
  87. }
  88.  
  89. void
  90. freetable(t, size)
  91.     node **t;
  92.     long size;
  93. {
  94. #ifdef MYMALLOC
  95.     extern void addtoheap();
  96.  
  97.     addtoheap((char *) t, size * sizeof(node *));
  98. #else
  99.     free((char *) t);
  100. #endif
  101. }
  102.  
  103. STATIC void
  104. nomem()
  105. {
  106.     static char epitaph[128];
  107.  
  108.     sprintf(epitaph, "out of memory (%ldk allocated)", allocation());
  109.     die(epitaph);
  110. }
  111.  
  112. /* data space allocation -- main sets `dataspace' very early */
  113. long
  114. allocation()
  115. {
  116.     static char *dataspace;
  117.     long rval;
  118.  
  119.     if (dataspace == 0) {        /* first time */
  120.         dataspace = sbrk(0);    /* &end? */
  121.         return 0;
  122.     }
  123.     rval = (sbrk(0) - dataspace)/1024;
  124.     if (rval < 0)            /* funny architecture? */
  125.         rval = -rval;
  126.     return rval;
  127. }
  128.  
  129. /* how much memory has been wasted? */
  130. void
  131. wasted()
  132. {
  133.     if (Memwaste == 0)
  134.         return;
  135.     vprintf(stderr, "memory allocator wasted %ld bytes\n", Memwaste);
  136. }
  137.  
  138. #ifdef MYMALLOC
  139.  
  140. /* use c library malloc/calloc here, and here only */
  141. #undef malloc
  142. #undef calloc
  143.  
  144. /* imports */
  145. #ifndef AMIGA
  146. extern char *malloc(), *calloc();
  147. #endif AMIGA
  148.  
  149. /* private */
  150. STATIC int align();
  151.  
  152. /* allocate in MBUFSIZ chunks.  4k works ok (less 16 for malloc quirks). */
  153. #define MBUFSIZ (4 * 1024 - 16)
  154.  
  155. /* 
  156.  * mess with ALIGN at your peril.  longword (== 0 mod 4)
  157.  * alignment seems to work everywhere.
  158.  */
  159.  
  160. #define ALIGN 2
  161.  
  162. typedef struct heap heap;
  163. struct heap {
  164.     heap *h_next;
  165.     long h_size;
  166. };
  167.  
  168. static heap *Mheap;    /* not to be confused with a priority queue */
  169.  
  170. STATIC void
  171. addtoheap(p, size)
  172.     char *p;
  173.     long size;
  174. {    int adjustment;
  175.     heap *pheap;
  176.  
  177.     /* p is aligned, but it doesn't hurt to check */
  178.     adjustment = align(p);
  179.     p += adjustment;
  180.     size -= adjustment;
  181.  
  182.     if (size < 1024)
  183.         return;        /* can't happen */
  184.     pheap = (heap *) p;    /* pheap is shorthand */
  185.     pheap->h_next = Mheap;
  186.     pheap->h_size = size;
  187.     Mheap = pheap;
  188. }
  189.  
  190. /*
  191.  * buffered malloc()
  192.  *    returns space initialized to 0.  calloc isn't used, since
  193.  *    strclear can be faster.
  194.  *
  195.  * free is ignored, except for very large objects,
  196.  * which are returned to the heap with addtoheap(). 
  197.  */
  198.  
  199. char    *
  200. mymalloc(n)
  201.     register unsigned int n;
  202. {    static unsigned int size; /* how much do we have on hand? */
  203.     static char *mstash;      /* where is it? */
  204.     register char *rval;
  205.  
  206.     if (n >= 1024) {        /* for hash table */
  207.         rval = (char *)malloc(n);    /* aligned */
  208.         if (rval)
  209.             strclear(rval, n);
  210.         return rval;
  211.     }
  212.  
  213.     n += align((char *) n);    /* keep everything aligned */
  214.  
  215.     if (n > size) {
  216.         Memwaste += size;    /* toss the fragment */
  217.         /* look in the heap */
  218.         if (Mheap) {
  219.             mstash = (char *) Mheap;    /* aligned */
  220.             size = Mheap->h_size;
  221.             Mheap = Mheap->h_next;
  222.         } else {
  223.             mstash = (char *)malloc(MBUFSIZ);    /* aligned */
  224.             if (mstash == 0) {
  225.                 size = 0;
  226.                 return 0;
  227.             }
  228.             size = MBUFSIZ;
  229.         }
  230.         strclear(mstash, size);        /* what if size > 2^16? */
  231.     }
  232.     rval = mstash;
  233.     mstash += n;
  234.     size -= n;
  235.     return rval;
  236. }
  237.  
  238. /*
  239.  * what's the (mis-)alignment of n?  return the complement of
  240.  * n mod 2^ALIGN
  241.  */
  242. STATIC int
  243. align(n)
  244.     char *n;
  245. {    register int abits;    /* misalignment bits in n */
  246.  
  247.     abits = (int) n & ~(0xff << ALIGN) & 0xff;
  248.     if (abits == 0)
  249.         return 0;
  250.     return (1 << ALIGN) - abits;
  251. }
  252.  
  253. #endif /*MYMALLOC*/
  254.