/* $RCSfile: mem.h,v $
 * 
 * $Author: halfdan $
 * $Date: 1999/03/18 17:23:20 $
 * $Revision: 1.2 $
 * 
 * $Log: mem.h,v $
 * Revision 1.2  1999/03/18  17:23:20  halfdan
 * Changed all types to internally defined types.
 * Added XMEM_strdup and related macros.
 *
 */

#ifndef MEM_H
#define MEM_H

#include <stdio.h>

// Untick this option if you want to use the XMEM functions
#ifdef DEBUG
#define XMEM
#endif

// Uncomment this option if XMEM should print out information
// each time a XMEM function is used (Other wise just the vmem_
// family is verbose).
// #define XMEM_VERBOSE

// Uncomment this option if XMEM should place guard words
// before and after each allocate block.
#define XMEM_GUARD_BYTES

// This value specifies how many guard words there should be
// before and after each block.
#define XMEM_GUARD_NO_WORDS			(32)

// This values specifies how many calls between each guard check.
#define XMEM_GUARD_CHECK_EACH		(1)

// This value defines the guard word
#define XMEM_GUARD_WORD				(0xDEADBEEF)

// Uncomment this if you want thread-safety built in. (Not implemented
// on all platforms).
#define XMEM_THREAD_SAFE

// Check if mental ray headers have been included
#if defined(_SHADER_H_) || defined(RAY2)
#define USE_MR_ALLOC
#endif

// A few handy #defines. Change to suit your platform

typedef unsigned int		xmem_uint32_t;
typedef unsigned char		xmem_uint8_t;


void *XMEM_alloc(const char *file, const int line, const int, int verbose);
void *XMEM_realloc(const char *file, const int line, void * const, const int, int verbose);
void XMEM_free(const char *file, const int line, void * const, int verbose);
char *XMEM_strdup(const char *file, const int line, char *str);
void XMEM_dump(void);
void XMEM_check(void);		// Do explicit guard check

#if defined(XMEM)

#define mem_allocate(x) XMEM_alloc(__FILE__, __LINE__, (x), FALSE)
#define mem_reallocate(p, x) XMEM_realloc(__FILE__, __LINE__, (p), (x), FALSE)
#define mem_release(p) XMEM_free(__FILE__, __LINE__, (p), FALSE)
#define mem_strdup(p) XMEM_strdup(__FILE__, __LINE__, (p))
#define mem_dump() XMEM_dump()
#define mem_check() XMEM_check()

#define vmem_allocate(x) XMEM_alloc(__FILE__, __LINE__, (x), TRUE)
#define vmem_reallocate(p, x) XMEM_realloc(__FILE__, __LINE__, (p), (x), TRUE)
#define vmem_release(p) XMEM_free(__FILE__, __LINE__, (p), TRUE)

#ifdef NEW
#undef NEW
#endif
#define NEW(type, no) ((type *)mem_allocate((no) * sizeof(type)))

#ifdef NEWC
#undef NEWC
#endif
#define NEWC(type, no) ((type *)mem_allocate((no) * sizeof(type)))

#ifdef DELETE
#undef DELETE
#endif
#define DELETE(ptr) if(ptr) mem_release(ptr)

#else

#ifdef USE_MR_ALLOC
#define mem_allocate(x) mi_mem_allocate(x)
#define mem_reallocate(p, x) mi_mem_reallocate((p), (x))
#define mem_release(p) mi_mem_release(p)
#define vmem_allocate(x) mi_mem_allocate(x)
#define vmem_reallocate(p, x) mi_mem_reallocate((p), (x))
#define vmem_release(p) mi_mem_release(p)
#else
#define mem_allocate(x) malloc(x)
#define mem_reallocate(p, x) realloc((p), (x))
#define mem_release(p) free(p)
#define mem_strdup(p) strdup(p)
#define vmem_allocate(x) malloc(x)
#define vmem_reallocate(p, x) realloc((p), (x))
#define vmem_release(p) free(p)
#endif

#define mem_dump()
#define mem_check()

#endif

#endif // MEM_H
