BSD 4_4_Lite2 development
[unix-history] / usr / src / contrib / mprof / mpattach.c
/* mpattach.c --
*
* mpattach.c 2.7 9/14/90 12:18:59
* Copyright (c) 1988, Benjamin G. Zorn
*
* This defines MPROF intermediate functions that call the actual
* malloc and free functions that have been renamed.
*/
extern char *__malloc__();
extern char *__realloc__();
extern int __free__();
extern int mprofing;
extern unsigned int *mprof();
extern void mprof_note_free();
extern void mprof_cleanup();
typedef struct {
int nbytes;
unsigned int *creators;
} mpheader;
#define MPROF_HEADER_SIZE (sizeof(mpheader))
\f
/* malloc -- Allocate header for mprof information on top of user bytes.
*
* Note that all objects have the extra header, but not all require
* profiling if the flag is turned off.
*/
char *
malloc(nbytes)
unsigned int nbytes;
{
char *result;
mpheader *force;
result = __malloc__(nbytes + MPROF_HEADER_SIZE);
/*
* Check for error on allocation.
*/
if (result == 0) {
return 0;
}
if (mprofing) {
mprofing = 0;
force = (mpheader *) result;
force->nbytes = nbytes;
force->creators = mprof(nbytes);
mprofing = 1;
}
return (char *) ((int) result + MPROF_HEADER_SIZE);
}
\f
/* realloc -- do the work of free than malloc, but call realloc to do
* it. (Provided by Mark Eichin, eichin@athena.mit.edu) Thanks.
*/
char *
realloc(cp, nbytes)
char *cp;
unsigned int nbytes;
{
mpheader *force;
char *realcp, *result;
/* not really mips specific */
/* the stupid X server I'm working on does this */
if (!cp) {
return (malloc(nbytes));
}
realcp = (char *) ((int) cp - MPROF_HEADER_SIZE);
if (mprofing) {
mprofing = 0;
force = (mpheader *) realcp;
mprof_note_free(force->creators, force->nbytes);
mprofing = 1;
}
result = __realloc__(realcp, nbytes + MPROF_HEADER_SIZE);
if (mprofing) {
mprofing = 0;
force = (mpheader *) result;
force->nbytes = nbytes;
force->creators = mprof(nbytes);
mprofing = 1;
}
return (char *) ((int) result + MPROF_HEADER_SIZE);
}
\f
/* free -- Free an object, coercing it back to the correct size.
*/
free(cp)
char *cp;
{
mpheader *force;
char *realcp;
realcp = (char *) ((int) cp - MPROF_HEADER_SIZE);
force = (mpheader *) realcp;
if (mprofing) {
mprofing = 0;
mprof_note_free(force->creators, force->nbytes);
mprofing = 1;
}
__free__(realcp);
}
\f
/* memalign -- Allocate aligned memory. This patch was provided by Robert
* Scheifler and handles calls to memalign and valloc on the Sun as long
* as the memory allocated is never later freed. Furthermore, unlike the
* real Sun memalign, the extra memory allocated is not freed.
*/
#include <errno.h>
extern int errno;
#define round_to(i, nearest) \
((((i) + (nearest) - 1) / (nearest)) * (nearest))
char *
memalign(alignment, nbytes)
unsigned int alignment;
unsigned int nbytes;
{
char *cp;
/*
* Check size and alignment parameters.
*/
if (nbytes == 0 || ((unsigned)(alignment) & 3)) {
errno = EINVAL;
return 0;
} else {
nbytes = round_to(nbytes, sizeof(int));
cp = malloc(nbytes + alignment);
return (char *) round_to((unsigned int) cp, alignment);
}
}
\f
/* valloc -- Allocate memory on a page-aligned boundary. This function
* uses memalign so the same problems occur (i.e. the memory allocated
* cannot later be freed and the extra memory allocated is lost).
*/
char *
valloc(nbytes)
unsigned int nbytes;
{
return memalign(getpagesize(), nbytes);
}
\f
/* exit -- mprof has its own version of exit so that the mprof file
* can be written and closed when mprof finishes.
* The sun doesn't need this because on_exit allows the user to add
* functions called on exit.
*/
#if defined(vax) || defined(mips)
exit(code)
int code;
{
void mprof_exit();
mprof_exit(code, 0);
_cleanup();
_exit(code);
}
#endif
void
mprof_exit(status, dummy)
int status;
char *dummy;
{
if (mprofing) {
mprofing = 0;
mprof_cleanup();
}
}