This is mem.c in view mode; [Download] [Up]
/* pathalias -- by steve bellovin, as told to peter honeyman */ #ifndef lint static char *sccsid = "@(#)mem.c 9.1 87/10/04"; #endif #include "def.h" /* exports */ extern void freelink(), wasted(); extern long allocation(); long Ncount; /* imports */ extern char *sbrk(); extern char *Netchars; extern int Vflag; extern void die(); /* privates */ STATIC void nomem(); STATIC unsigned align(); static link *Lcache; static unsigned int Memwaste; link * newlink() { register link *rval; if (Lcache) { rval = Lcache; Lcache = Lcache->l_next; strclear((char *) rval, (int)sizeof(link)); } else if ((rval = (link * ) calloc(1, sizeof(link))) == 0) nomem(); return rval; } /* caution: this destroys the contents of l_next */ void freelink(l) link *l; { l->l_next = Lcache; Lcache = l; } node * newnode() { register node *rval; if ((rval = (node * ) calloc(1, sizeof(node))) == 0) nomem(); Ncount++; return rval; } char * strsave(s) char *s; { register char *r; if ((r = malloc((unsigned) strlen(s) + 1)) == 0) nomem(); (void) strcpy(r, s); return r; } #ifndef strclear void strclear(str, len) register char *str; register long len; { while (--len >= 0) *str++ = 0; } #endif /*strclear*/ #ifndef M_I286 node ** newtable(size) long size; { register node **rval; if ((rval = (node **) calloc(1, (unsigned int) size * sizeof(node *))) == 0) nomem(); return rval; } #endif /* !M_I286 */ #ifndef M_I286 freetable(t, size) node **t; long size; { #ifdef MYMALLOC addtoheap((char *) t, (int)sizeof(node *) * size); #else free((char *) t); #endif } #endif /* !M_I286 */ STATIC void nomem() { static char epitaph[128]; sprintf(epitaph, "out of memory (%ldk allocated)", allocation()); die(epitaph); } /* data space allocation -- main sets `dataspace' very early */ long allocation() #ifdef M_I286 { /* * it _may_ be possible to determine total allocation on the '286, * but I'm not going to bother trying. */ return 0; } #else /* !M_I286 */ { static char *dataspace; long rval; if (dataspace == 0) { /* first time */ dataspace = sbrk(0); /* &end? */ return 0; } rval = (sbrk(0) - dataspace)/1024; if (rval < 0) /* funny architecture? */ rval = -rval; return rval; } #endif /* !M_I286 */ /* how much memory has been wasted? */ void wasted() { if (Memwaste == 0) return; vprintf(stderr, "memory allocator wasted %ld bytes\n", Memwaste); } #ifdef MYMALLOC /* use c library malloc/calloc here, and here only */ #undef malloc #undef calloc extern char *malloc(), *calloc(); /* allocate in MBUFSIZ chunks. 4k works ok (less 16 for malloc quirks). */ #define MBUFSIZ (4 * 1024 - 16) /* * mess with ALIGN at your peril. longword (== 0 mod 4) * alignment seems to work everywhere. */ #ifdef M_I286 # define ALIGN 1 #else # define ALIGN 2 #endif typedef struct heap heap; struct heap { heap *h_next; long h_size; }; static heap *Mheap; /* not to be confused with a priority queue */ addtoheap(p, size) char *p; long size; { int adjustment; heap *pheap; /* p is aligned, but it doesn't hurt to check */ adjustment = align((unsigned) p); p += adjustment; size -= adjustment; if (size < 1024) return; /* can't happen */ pheap = (heap *) p; /* pheap is shorthand */ pheap->h_next = Mheap; pheap->h_size = size; Mheap = pheap; } /* * buffered malloc() * returns space initialized to 0. calloc isn't used, since * strclear can be faster. * * free is ignored, except for very large objects, * which are returned to the heap with addtoheap(). */ char * mymalloc(n) register unsigned int n; { static unsigned int size; /* how much do we have on hand? */ static char *mstash; /* where is it? */ register char *rval; if (n >= 1024) { /* for hash table */ rval = malloc(n); /* aligned */ if (rval) strclear(rval, (int)n); return rval; } n += align(n); /* keep everything aligned */ if (n > size) { Memwaste += size; /* toss the fragment */ /* look in the heap */ if (Mheap) { mstash = (char *) Mheap; /* aligned */ size = Mheap->h_size; Mheap = Mheap->h_next; } else { mstash = malloc(MBUFSIZ); /* aligned */ if (mstash == 0) { size = 0; return 0; } size = MBUFSIZ; } strclear(mstash, (int)size); /* what if size > 2^16? */ } rval = mstash; mstash += n; size -= n; return rval; } /* * what's the (mis-)alignment of n? return the complement of * n mod 2^ALIGN */ STATIC unsigned align(n) unsigned n; { register unsigned abits; /* misalignment bits in n */ abits = n & (~(0xff << ALIGN) & 0xff); if (abits == 0) return 0; return (1 << ALIGN) - abits; } #endif /*MYMALLOC*/
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.