|
|
//-----------------------------------------------------------------------------
//
// File: TRANSMEM.H
//
// Copyright Microsoft Corporation 1997, All Rights Reserved.
//
// Owner: NIKOS
//
// Description: This file contains memory routines and macros for using
// EXCHMEM as a dynamic memory allocator. If your object can
// be made fixed in size, it may be more appropriate to use
// CPool especially if your object is allocated/freed often.
//
// Note: CPool never releases (frees) objects, so some sort of
// free such objects may also be needed.
//
// Modified 2/98 by mikeswa - Added Multi-heap support
//-----------------------------------------------------------------------------
#ifndef __TRANSMEM_H__
#define __TRANSMEM_H__
#include <exchmem.h>
#include <cpool.h>
#define HEAP_LOW_MEMORY_RESERVE 65536 // to be freed when we're low on memory
//define number of exchmem heaps if not already defined
#ifndef NUM_EXCHMEM_HEAPS
#define NUM_EXCHMEM_HEAPS 0
#endif //NUM_EXCHMEM_HEAPS
//
// These three globals:
//
// HANDLE g_hTransHeap = NULL;
//
// must be declared somewhere in a C file so things will link properly. The macros
// declared use these to store heap handles, etc. to make things work.
//
#ifdef __cplusplus
extern "C" { #endif
extern HANDLE g_hTransHeap; #ifdef __cplusplus
} #endif
//
// TrHeapCreate needs to be called once at startup time to initialize Exchmem and create
// the heap.
//
#ifdef __cplusplus
__inline BOOL TrHeapCreate(DWORD dwFlags=0, DWORD dwInitialSize=1024000, DWORD dwMaxSize=0) #else
__inline BOOL TrHeapCreate(DWORD dwFlags, DWORD dwInitialSize, DWORD dwMaxSize) #endif
{ if (g_hTransHeap) return FALSE;
g_hTransHeap = ExchMHeapCreate(NUM_EXCHMEM_HEAPS, dwFlags, dwInitialSize, dwMaxSize);
if (g_hTransHeap) return TRUE; else return FALSE; }
//
// TrHeapDestroy() needs to be called once at shutdown time to free the heap and it's contents.
//
// Note: Because the heap is destroyed before the module is finished unloading, all objects that
// allocated memory must be destroyed (with delete) before the module is unloaded. If not
// done, nasty crashes will result. This is a BAD thing to do:
//
// CObject g_Object;
//
// CObject::~CObject()
// {
// if (NULL != m_pBuffer)
// {
// TrFree(m_pBuffer);
// m_pBuffer = NULL;
// }
// }
//
// since ~CObject() will be called AFTER TrHeapDestroy, and TrFree will be called on a (destroyed) heap.
//
__inline BOOL TrHeapDestroy(void) { BOOL b = TRUE;
if (g_hTransHeap) { b = ExchMHeapDestroy(); g_hTransHeap = NULL; }
return b; }
//
// TrCalloc: replacement for calloc()
//
__inline void * TrCalloc(unsigned int x, unsigned int y, char * szFile = __FILE__, unsigned int uiLine = __LINE__) { return g_hTransHeap ? ExchMHeapAllocDebug(x*y, szFile, uiLine) : NULL; }
//
// TrFree: replacement for free()
__inline void TrFree(void *pv) { if (g_hTransHeap) { ExchMHeapFree(pv); } else { // Our allocs / frees are out of sync.
#ifdef DEBUG
DebugBreak(); #endif
} }
// TrMalloc: replacement for malloc()
__inline void * TrMalloc(unsigned int size, char * szFile = __FILE__, unsigned int uiLine = __LINE__) { return g_hTransHeap ? ExchMHeapAllocDebug(size, szFile, uiLine) : NULL; }
// TrRealloc: replacement for realloc()
__inline void * TrRealloc(void *pv, unsigned int size, char * szFile = __FILE__, unsigned int uiLine = __LINE__) { return g_hTransHeap ? ExchMHeapReAllocDebug(pv, size, szFile, uiLine) : NULL; }
#ifdef __cplusplus
#define TransCONST const
#else
#define TransCONST
#endif
// TrStrdupW: replacement for wcsdup()
__inline LPWSTR TrStrdupW(TransCONST LPWSTR pwszString) { LPWSTR pwszTmp = NULL; if (NULL == g_hTransHeap || NULL == pwszString) return NULL; pwszTmp = (LPWSTR) ExchMHeapAlloc((wcslen(pwszString) + 1) * sizeof(WCHAR)); if (NULL != pwszTmp) wcscpy(pwszTmp,pwszString);
return pwszTmp; }
// TrStrdupA: replacement for strdup()
__inline LPSTR TrStrdupA(TransCONST LPSTR pszString) { LPSTR pszTmp = NULL; if (NULL == g_hTransHeap || NULL == pszString) return NULL; pszTmp = (LPSTR) ExchMHeapAlloc((strlen(pszString) + 1) * sizeof(CHAR)); if (NULL != pszTmp) strcpy(pszTmp,pszString);
return pszTmp; }
#ifdef _UNICODE
#define TrStrdup(x) TrStrdupW(x)
#else
#define TrStrdup(x) TrStrdupA(x)
#endif
//
// Please use the pv* macros... defined here allocators may change over time and this will
// make it easy to change when needed.
//
#define pvMalloc(x) TrMalloc(x, __FILE__, __LINE__)
#define FreePv(x) TrFree(x)
#define pvCalloc(x,y) TrCalloc(x,y, __FILE__, __LINE__)
#define pszStrdup(x) TrStrdup(x)
#define pvRealloc(pv,size) TrRealloc(pv, size, __FILE__, __LINE__)
#ifdef __cplusplus
// Replacement for the default new() operator
__inline void * __cdecl operator new(size_t stAllocateBlock) { return TrMalloc( stAllocateBlock ); }
// Replacement for the default new() operator that allows
//specification of file and line #
// To use this allocator as your default allocator, simply use the following:
//#define new TRANSMEM_NEW
//NOTE: You must be careful when you redefine this macro... it may cause
//problems with overloaded new operators (a la CPOOL or STL).
#define TRANSMEM_NEW new(__FILE__, __LINE)
__inline void * __cdecl operator new(size_t stAllocateBlock, char * szFile, unsigned int uiLine) { return TrMalloc( stAllocateBlock, szFile, uiLine ); } // Replacement for the default delete() operator
__inline void __cdecl operator delete( void *pvMem ) { FreePv( pvMem ); }
#endif
// Convenient macro to set the pointer you freed to NULL as well
#define TRFREE(x) \
if (NULL != x) \ { \ FreePv(x); \ x = NULL; \ }
// Convenient macro to set the pointer to the object to NULL as well
#define TRDELETE(x) \
if (NULL != x) \ { \ delete x; \ x = NULL; \ }
#endif /* __TRANSMEM_H__ */
|