/* $Header: /smsa/bsd:include/malloc.h:bsd  1.6  $
 * $Source: /smsa/bsd:include/malloc.h: $
 *
 * Copyright (c) 1989 Acorn Computers Ltd
 */

#ifndef __malloc_h
#define __malloc_h

/*
 * NOTE
 *
 * This header file is for compatibility with the SVID, and for backwards
 * compatibility with old versions of XPG.  Please use stdlib.h instead -
 * and stick to the ANSI C interface.
 */
/*
 * Changes since RISC iX 1.13 -
 *
 * +	M_LOWMEM has been removed, as has the reservation of space using
 *	setrlimit.  The latter was not sufficiently portable, the former
 *	was (effectively) an inconvenient interface.  M_NOMEM now allows
 *	arbitrary storage manager actions (particularly free()) when the
 *	system is about to run out of memory.  M_LOWMEM will be faulted
 *	in RISC iX 1.2 (that's why you're looking at this header file,
 *	isn't it?)
 */
/*
 * ANSI says that non-ANSI functions should be in the semi-reserved or
 * reserved name spaces, so there is no mallopt or mallinfo in this
 * implementation - instead this header file defines suitable
 * alternatives.
 */
#define mallopt		_ALLOC_Options
#define mallinfo	_ALLOC_Info

/*
 * The SVID information structure - this does not give any really meaningful
 * information about this storage manager.  Use the statistical functions below
 * in preference.  The smblks figure is particularly unreliable - it is an
 * estimate based on examination of the heap, it does not take into account
 * calls to brk(2) or sbrk(2) which have been interleaved with malloc(3) calls.
 * The usmblks figure is calculated from hblks*2048-fsmblks, so is similarly
 * approximate.
 */
typedef struct _ALLOC_Info {
	int	arena;		/* total space in in heap including overheads */
	int	ordblks;	/* total number of large blocks (fragmentation) */
	int	smblks;		/* total number of small blocks (APPROXIMATE) */
	int	hblkhd;		/* total space allocate to chunk tables */
	int	hblks;		/* total number of chunks (APPROXIMATE) */
	int	usmblks;	/* space currently allocated in small blocks */
	int	fsmblks;	/* space currently free in small blocks */
	int	uordblks;	/* space currently allocated in large blocks */
				/* this EXCLUDES the space in the headers of these blocks */
	int	fordblks;	/* space currently available in large blocks */
				/* this EXCLUDES the space in the headers of these */
	int	keepcost;	/* always 0 */
} _ALLOC_info;

/*
 * The functions malloc, free and realloc are not defined in
 * this header, because definitions in existing code would
 * probably clash.
 */
extern const char	*_ALLOC_Id(void);
extern int		_ALLOC_ResetBlockMap(const unsigned char /*blockMap*/[256]);
extern int		_ALLOC_StorageInUse(void);
extern int		_ALLOC_FreeBlocks(unsigned /*size*/);
extern int		_ALLOC_FreeWordsLarge(void);
extern int		_ALLOC_StorageFree(void);
extern int		_ALLOC_Options(int /*cmd*/, int /*value*/);
extern _ALLOC_info	_ALLOC_Info(void);
extern unsigned		_byte_size(void * /*ptr*/);

/*
 * Definitions of the commands for _ALLOC_Options.
 */
#define M_MXFAST	1
#define M_NLBLKS	2
#define M_GRAIN		3
#define M_KEEP		4
/*
 * Additions to the SVID
 */
#define M_FLTFREE	0x81	/* abort(3) when free fails		[on]  */
#define M_FLTMALLOC	0x82	/* abort(3) when alloc fails		[off] */
#define M_FLTSMASH	0x83	/* abort(3) when store is corrupted	[on]  */
#define M_MALLOC0	0x84	/* return valid store from malloc(0)	[off] */

/*
 *------------The following functionality has been removed--------------------
 * It is also possible to specify a function to call when the storage manager
 * notices that memory is getting low.  The function is called with no 
 * arguments from INSIDE the storage manager.  It must take care not to cause
 * any use (directly or indirectly) of the storage manager.  If it returns
 * 1 it is assumed that it has arranged for more store to be available to
 * a subsequent sbrk() call - eg via setrlimit(2).  If it returns 0 the
 * storage manager will use its own mechanism to get more store by calling
 * setrlimit(2) itself.  Notice that the storage manager ensures that the
 * first call to setrlimit(2) will work by decreasing the rlim_data value
 * when it is initialised.  The default low memory handler simply outputs
 * a message (on stream 2 - not using fprintf of course (this function could
 * call the storage manager)).
 *----------------------------------------------------------------------------
 *
 * Two functions may be defined to handle warning and error messages.
 * Both functions are of type (void (*)(char *)).  If the error handler is defined
 * it is not expected to return - if it does return the storage manager will normally
 * return 0 (from a free() call this means success, from a malloc() call or realloc()
 * call failure).  If the error handler is not defined the warning handler is used
 * instead and a call is made to abort(3) to terminate the program.  These functions
 * are called in a context which is outside the storage manager - so, in theory,
 * they are free to use it, however they almost invariably called as the result of
 * an error - so use of the storage manager may fail.  The error handlers will not
 * be called recursively - if an attempt at a recursive call is detected abort(3)
 * is called, if this would result in a recursive call of abort(3) the storage
 * manager simply returns (resulting in a NULL return from malloc/realloc).
 *
 * An interface may be specified which will be called when a malloc() or
 * realloc() call is about to fail.  The supplied function is effectively called
 * as though it were malloc().  It is passed the number of bytes required (as the
 * original malloc() call, or as passed to realloc()).  This function is called
 * OUTSIDE the storage manager - so it may make free() calls as required.  The
 * result of the function is the result of the original malloc() or realloc()
 * call - if the function is called as a result of realloc() the original pointer
 * contents will be copied into the new space and the original pointer freed.
 * The function should either return NULL if the storage is not available or
 * call abort(3), as required by the program.  This routine must protect itself
 * from making recursive calls if it calls malloc(3).  If this interface is specified
 * the setting of M_FLTMALLOC is ignored - if the function given returns NULL this
 * will be the result of the malloc or realloc call.  The called function is
 * expected to set ENOMEM in errno if it fails!
 */
/*- #define M_LOWMEM	0x91	* used to be an (int (*)(void)) function to handle low memory */
#define M_WARNING	0x92	/* specify a (void (*)(const char *)) function */
#define M_ERROR		0x93	/* specify a (void (*)(const char *)) function */
#define M_NOMEM		0x94	/* specify a (void *(*)(unsigned)) function */

#endif/*__malloc_h*/

/* EOF malloc.h */
