|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 4671 (0x123f)
Types: TextFile
Names: »mem.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦2fafebccf⟧ »EurOpenD3/mail/smail3.1.19.tar.Z«
└─⟦bcd2bc73f⟧
└─⟦this⟧ »pd/pathalias/mem.c«
/* 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*/