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

Defined functions

addtoheap defined in line 226; used 1 times
align defined in line 297; used 2 times
allocation defined in line 172; used 8 times
freetable defined in line 151; used 1 times
mymalloc defined in line 254; never used
newnode defined in line 93; used 5 times
newtable defined in line 140; used 3 times
nomem defined in line 162; used 7 times
strclear defined in line 130; never used
strsave defined in line 118; used 5 times
wasted defined in line 193; used 3 times

Defined variables

Lcache defined in line 26; used 6 times
Memwaste defined in line 28; used 3 times
Mheap defined in line 224; used 7 times
Ncount defined in line 11; used 4 times
sccsid defined in line 3; never used

Defined struct's

heap defined in line 219; used 1 times

Defined typedef's

heap defined in line 218; used 4 times

Defined macros

ALIGN defined in line 216; used 2 times
MBUFSIZ defined in line 209; used 2 times
Last modified: 1988-04-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4138
Valid CSS Valid XHTML 1.0 Strict