.TH MALLOC 3
.UC 4
.SH NAME
mallocMagic, freeMagic \- a new memory allocator in libmagicutils.a

.SH SYNOPSIS
.nf
.B #include "magic.h"
.B #include "malloc.h"
.PP
.B "char *mallocMagic(size)"
.B unsigned size;
.PP
.B "char *callocMagic(size)"
.B unsigned size;
.PP
\fBMALLOC(\fItype_decl\fB, var, size)\fR
.B \fItype_decl\fB var;
.B unsigned size;
.PP
\fBCALLOC(\fItype_decl\fB, var, size)\fR
.B \fItype_decl\fB var;
.B unsigned size;
.PP
.B "freeMagic(var)"
.B char *var;
.PP
.B "FREE(var)"
.B char *var;
.PP
.B "cc -DMALLOCTRACE ... ~cad/src/magic/lib/libmagictrace.a"
.PP
.B mallocTraceInit(filename)
.B char *filename;
.PP
.B mallocTraceEnable()
.PP
.B mallocTraceDisable()
.PP
.B mallocTraceDone()
.PP
.B mallocTraceOnlyWatched(only)
.B bool only;
.PP
.B bool mallocTraceWatch(addr)
.B char *addr;
.PP
.B bool mallocTraceUnWatch(addr)
.B char *addr;

.SH DESCRIPTION
These procedures implement a new memory allocator.
They provide fast allocation and freeing for
programs that allocate thousands or
millions of objects of similar sizes.
Speed results from maintaining separate free-lists for objects
of each size, providing fast macros \fIMALLOC\fR and \fIFREE\fR
for doing allocation and freeing, and clustering objects of the
same size on the same page in an attempt to improve locality of
reference.
In addition, these procedures
provide features to aid in the debugging of programs that
do a lot of memory allocation and freeing; used in conjunction
with \fIprleak\fR\|(8) they can detect storage leaks and
also duplicate attempts to free the same storage location.
.PP
Memory is allocated using either the procedure \fImallocMagic\fR
or the macro \fIMALLOC\fR.  The former has an interface identical
to that of the standard UNIX library procedure \fImalloc\fR\|(3),
namely, it returns a pointer to a region of memory sufficiently
large to hold \fIsize\fR bytes.
The macro \fIMALLOC\fR is noticeably faster, particularly on
machines with brain-dead procedure calls (such as a certain
popular machine made by the second largest U.S. computer
manufacturer).  Its usage is a bit unusual, in that its
first argument is a type specification and its second is
modified in place.  For example, to allocate an object of
type \fIHashEntry *\fR that is 20 bytes long, and to assign
this to the pointer \fIhe\fR, one could write:
.sp
.ti +1i
\fBMALLOC(HashEntry *, he, 20);\fR
.sp
Note that there are no parentheses around the \fBHashEntry *\fR above.
After executing this macro, \fIhe\fR would point to a \fIHashEntry\fR
that was 20 bytes long.
.PP
The macro \fICALLOC\fR and the procedure \fIcallocMagic\fR perform
function analagous to \fIMALLOC\fR and \fImallocMagic\fR except that
the malloc'd memory is zeroed.
.PP
Memory can be freed using either the procedure \fIfreeMagic\fR,
which frees its argument \fIvar\fR exactly as does the UNIX \fIfree\fR\|(3),
or using the \fIFREE\fR macro, which does the same thing to \fIvar\fR
but is faster.
.PP
Users of \fIMALLOC\fR and \fIFREE\fR should beware that they are
macros that include C statements enclosed in a pair of braces (\fB{\ ...\ }\fR),
and should be treated accordingly.  For example, it is not legal to
type:
.sp
.in +1i
.nf
.ta +1i
\fBif (i != j)
	MALLOC(HashEntry *, he, i);
else
	return (NULL);\fR
.fi
.in -1i
One should instead use:
.sp
.in +1i
.nf
.ta +1i
\fBif (i != j)
{
	MALLOC(HashEntry *, he, i);
}
else
	return (NULL);\fR
.fi
.in -1i
.PP
If you wish to take advantage of the debugging features of this
memory allocator, you must do two things.  First, compile all
of your \fB.c\fR files that #include ``malloc.h'' with the
\fB-DMALLOCTRACE\fR flag.  Second, when you link your program
to build an \fIa.out\fR file, use the library
\fB~cad/src/magic/lib/libmagictrace.a\fR
instead of the normal \fBlibmagicutils.a\fR.
The \fBlibmagictrace.a\fR library contains additional code to
maintain the information needed by the debugging procedures
below.  If you link your program with the standard library,
it will link successfully, but the debugging procedures won't
do anything.
.PP
The debugging procedures produce a trace file for subsequent
analysis by \fIprleak\fR\|(8).
Before any memory is allocated, you should call \fImallocTraceInit\fR
to create the trace file \fIname\fR.  Tracing won't actually begin,
however, until you call \fImallocTraceEnable\fR.  From that point
until \fImallocTraceDisable\fR, all calls to \fImallocMagic\fR
or \fIfreeMagic\fR (or their corresponding macro versions \fIMALLOC\fR
and \fIFREE\fR) will be logged to the trace file.  Calls to
\fImallocTraceDisable\fR and \fImallocTraceEnable\fR may be nested;
only the outermost \fImallocTraceEnable\fR has any effect.
.PP
If more selective tracing is desired, you can specify that trace
information is to be output only for certain addresses.
Calling \fImallocTraceOnlyWatched\fR with \fIonly\fR equal to \fBTRUE\fR
causes this to happen.
An address \fIaddr\fR is added to the list of addresses to trace by
calling \fImallocTraceWatch\fR, or removed from this list by calling
\fImallocTraceUnWatch\fR.  When \fImallocTraceOnlyWatched\fR is
called with \fIonly\fR equal to \fBFALSE\fR, operation reverts to
the normal mode of tracing all addresses.
.PP
When you are finished with all memory allocation tracing and want
to flush all results out to the trace file, call \fImallocTraceDone\fR.
Subsequent calls to the memory allocator will not be traced.

.SH BUGS
The \fIMALLOC\fR and \fIFREE\fR macros are syntactically clumsy,
but unfortunately some C optimizers have trouble with syntactically
cleaner forms.
.sp
The ability to trace specific addresses is only useful if you
know which ones to watch.  A more generally useful facility
would probably be to watch certain sizes of objects, or to
allow the user to supply a procedure that could determine
whether or not an address was to be traced.

.SH SEE ALSO
magicutils\|(3)