ngspice/xgraph/alloc.c

285 lines
5.2 KiB
C

/* $Header$ */
/*
*
* alloc.c : Memory checked Malloc. This malloc keeps track of memory usage.
*
* Routines:
* char * Malloc();
* char * Calloc();
* char * Realloc();
* void Free();
* unsigned MemStat();
* unsigned MemPtr();
* void MemChain();
*
* $Log$
* Revision 1.1 2004-01-25 09:00:49 pnenzi
*
* Added xgraph plotting program.
*
* Revision 1.1.1.1 1999/12/03 23:15:53 heideman
* xgraph-12.0
*
* Revision 1.10 1991/02/01 08:12:55 christos
* Overhaul... Simplified and added calloc.
*
* Revision 1.9 1990/10/02 18:11:24 christos
* Another Realloc() bug!
*
* Revision 1.8 90/10/02 17:32:45 christos
* Fixed Realloc() bug.
*
* Revision 1.7 90/08/24 02:28:15 christos
* Changed bigstruct_t to align_t
* for lint.
*
* Revision 1.6 90/07/15 17:31:33 christos
* Fixed MemPtr Bug
*
* Revision 1.5 90/07/11 16:19:31 christos
* Added Realloc()
*
* Revision 1.4 90/03/21 12:58:44 christos
* Fixed void buggy computations.
*
* Revision 1.3 90/02/26 02:15:11 christos
* ANSI conformance.
*
* Revision 1.2 89/08/29 14:08:25 christos
* Fixed.
*
* Revision 1.1 89/03/27 14:23:40 christos
* Initial revision
*
*/
#ifndef lint
static char rcsid[] = "$Id$";
#endif /* lint */
#include <stdio.h>
#ifdef __STDC__
#include <stdlib.h>
#include <memory.h>
#else
extern char *malloc();
extern char *calloc();
extern char *realloc();
extern void free();
extern void abort();
extern char *memset();
#endif
#ifndef NIL
#define NIL(a) ((a *) 0)
#endif /* NIL */
#ifndef MIN
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#endif /* MIN */
#ifndef MAX
#define MAX(a, b) ((a) < (b) ? (b) : (a))
#endif /* MAX */
#ifndef private
#define private static
#endif /* private */
#ifndef public
#define public
#endif /* public */
#define SIG_GOOD 0x01020304
#define SIG_FREE 0x04030201
#define OVERHEAD (sizeof(long) + sizeof(unsigned))
private unsigned memused = 0;
private unsigned memalloc = 0;
#ifdef __STDC__
typedef void *Ptr;
#else
typedef char *Ptr;
#endif
/* _chaina():
* Check things for validity and allocate space
*/
private Ptr
_chaina(n, routine, action, tptr)
unsigned n;
Ptr(*routine) ();
char *action;
Ptr tptr;
{
char *ptr;
if (n == 0) {
(void) fprintf(stderr, "*** %s zero length block.\n",
action);
if (tptr != (Ptr) 0) {
ptr = tptr;
*((long *) ptr) = SIG_GOOD;
memused += *((unsigned *) &ptr[sizeof(long)]);
memalloc++;
}
abort();
}
ptr = (tptr == (Ptr) 0) ? (char *) (*routine) (n + OVERHEAD) :
(char *) (*routine) (tptr, n + OVERHEAD);
if (ptr == NIL(char)) {
if (tptr != (Ptr) 0)
*((long *) tptr) = SIG_GOOD;
(void) fprintf(stderr,
"*** Out of memory in %s (current allocation %d).\n",
action, memused, n);
abort();
}
*((long *) ptr) = SIG_GOOD;
memused += (*((unsigned *) &ptr[sizeof(long)]) = n);
memalloc++;
ptr += OVERHEAD;
return ((Ptr) ptr);
} /* end _chaina */
/* _chainc():
* Check the pointer given
*/
private unsigned
_chainc(ptr, action)
char **ptr;
char *action;
{
static char *msg = "*** %s %s pointer.\n";
if (*ptr == NIL(char)) {
(void) fprintf(stderr, msg, action, "nil");
abort();
}
*ptr -= OVERHEAD;
switch (*((long *) *ptr)) {
case SIG_GOOD:
return (*((unsigned *) &((*ptr)[sizeof(long)])));
case SIG_FREE:
(void) fprintf(stderr, msg, action, "free");
abort();
default:
(void) fprintf(stderr, msg, action, "invalid");
abort();
}
return (0);
} /* end _chainc */
/* Malloc():
* real alloc
*/
public Ptr
Malloc(n)
unsigned n;
{
static char *routine = "malloc";
return (_chaina(n, malloc, routine, (Ptr) 0));
} /* end Malloc */
/* Calloc():
* real alloc
*/
public Ptr
Calloc(n, sz)
unsigned n,
sz;
{
Ptr ptr;
static char *routine = "calloc";
n *= sz;
ptr = _chaina(n, malloc, routine, (Ptr) 0);
memset((char *) ptr, 0, n);
return (ptr);
} /* end Calloc */
/* Realloc():
* real alloc
*/
public Ptr
Realloc(ptr, n)
Ptr ptr;
unsigned n;
{
static char *routine = "realloc";
memused -= _chainc((char **) &ptr, routine);
memalloc--;
*((long *) ptr) = SIG_FREE;
return (_chaina(n, realloc, routine, ptr));
} /* end Realloc */
/* Free():
* free memory counting the number of bytes freed
*/
public void
Free(ptr)
Ptr ptr;
{
static char *routine = "free";
memused -= _chainc((char **) &ptr, routine);
memalloc--;
*((long *) ptr) = SIG_FREE;
free(ptr);
} /* end Free */
/* MemChain():
* Dump the chain
*/
public void
MemChain()
{
if (memused == 0 && memalloc == 0)
(void) fprintf(stdout, "\tNo memory allocated.\n");
else {
(void) fprintf(stdout, "\t%u Bytes allocated in %u chunks.\n", memused,
memalloc);
(void) fprintf(stdout, "\tAverage chunk length %u bytes.\n",
memused / memalloc);
}
} /* end MemChain */
/* MemStat():
* return the amount of memory in use
*/
public unsigned
MemStat()
{
return (memused);
} /* end MemStat */
/* MemPtr():
* return the amount of memory used by the pointer
*/
public unsigned
MemPtr(ptr)
Ptr ptr;
{
static char *routine = "get size";
return (_chainc((char **) &ptr, routine));
} /* end MemPtr */