home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / pathalias_V10.lzh / mem.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  5KB  |  269 lines

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