162 lines
5.1 KiB
C++
162 lines
5.1 KiB
C++
/*
|
|
ZAlloc.hpp (created 9/12/10)
|
|
Author : James Russell
|
|
|
|
Purpose :
|
|
|
|
Memory allocation library and memory allocation tracker for ZEngine. If ZALLOC_EXTRA_SPAMMY is defined,
|
|
then allocations will log a message to stderr when allocation occurs indicating how much.
|
|
|
|
License:
|
|
|
|
TODO
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#ifndef _ZALLOC_H
|
|
#define _ZALLOC_H
|
|
|
|
#include <ZUtil/ZUtilBuild.hpp>
|
|
|
|
#include <new>
|
|
|
|
//The compiler really should be smart enough to include size_t in the global
|
|
//namespace by default. But, on some Linux configurations, it will drop
|
|
//it in std. Explicitly including this doesn't hurt anything.
|
|
#include <stddef.h>
|
|
|
|
#if ZALLOC_CHECK_ALLOC
|
|
|
|
//Memory Checkpoint Struct
|
|
struct ZMemState
|
|
{
|
|
int Checkpoint; //Checkpoint Number
|
|
};
|
|
|
|
//Allocation Info Struct
|
|
struct ZAllocInfo
|
|
{
|
|
static int CurrentAllocCount; //Current number of unfreed allocations
|
|
static int CurrentCheckpoint; //Static current checkpoint tracker
|
|
|
|
ZAllocInfo* Next; //Next Info Node
|
|
uintptr_t Address; //Address assigned
|
|
size_t Size; //Size of the allocation
|
|
int Line; //Line Number
|
|
int Checkpoint; //Checkpoint Integer
|
|
char File[128]; //File String
|
|
};
|
|
|
|
//Adds a tracking node for an allocation
|
|
extern void ZAllocAddTrack(uintptr_t _address, size_t _size, const char *_file, int _line, int _checkpoint);
|
|
|
|
//Removes a tracking node for an allocation
|
|
extern void ZAllocRemoveTrack(uintptr_t _address);
|
|
|
|
//Dumps unfreed memory string containing a list of memory leaks
|
|
extern void ZAllocDumpUnfreed(ZMemState *_state);
|
|
|
|
//Debug Placement Operator New
|
|
extern void* operator new(size_t _size, const char *_file, int _line, int _checkpoint) throw();
|
|
extern void* operator new[](size_t _size, const char *_file, int _line, int _checkpoint) throw();
|
|
|
|
//Debug Placement Delete
|
|
extern void operator delete(void *_ptr, const char* _file, int _line, int _checkpoint);
|
|
extern void operator delete[](void *_ptr, const char* _file, int _line, int _checkpoint);
|
|
|
|
//Our arguments to znew
|
|
#define ZNEW_ARGS (__FILE__, __LINE__, ZAllocInfo::CurrentCheckpoint)
|
|
|
|
//Macros for declaring a memory 'checkpoint' and
|
|
//dumping memory leaks to stderr
|
|
#define ZALLOC_MEM_CHECKPOINT(stateP) stateP->Checkpoint = AtomicAddReturn((volatile int*)&ZAllocInfo::CurrentCheckpoint, 1)
|
|
#define ZALLOC_MEM_DUMP_LEAKS(stateP) ZAllocDumpUnfreed(stateP)
|
|
|
|
#else //!ZALLOC_CHECK_ALLOC
|
|
|
|
#define ZNEW_ARGS (std::nothrow)
|
|
|
|
#define ZALLOC_MEM_CHECKPOINT(stateP)
|
|
#define ZALLOC_MEM_DUMP_LEAKS(stateP)
|
|
|
|
#endif //ZALLOC_CHECK_ALLOC
|
|
|
|
/* Some definitions we need for znew_static */
|
|
|
|
//This is used to indicate a static allocation (basically a type flag)
|
|
struct znew_static_t { };
|
|
|
|
//Our actual static allocation overrides
|
|
extern void* operator new(size_t _size, znew_static_t _staticAlloc);
|
|
extern void* operator new[](size_t _size, znew_static_t _staticAlloc);
|
|
|
|
/* Some Memory Management Macros */
|
|
|
|
//znew loves you!
|
|
#define znew new ZNEW_ARGS //Allocate with params
|
|
#define znew_notrack new (std::nothrow) //Allocate without tracking
|
|
#define znew_static new (znew_static_t()) //Allocate, but register for delete onexit
|
|
#define zdelete delete //Delete
|
|
|
|
#define zalloc(_type, _size) ZAlloc::Alloc<_type>(_size) //Allocates an array (block of memory) using the ZAlloc allocation library
|
|
#define zfree(_data) ZAlloc::Free(_data) //Frees an array (block of memory) using the ZAlloc allocation library
|
|
|
|
#define MemCopy(_type, _dest, _src, _count) memcpy(_dest, _src, _count * sizeof(_type))
|
|
#define MemCopyFloat(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(float))
|
|
#define MemCopyInt(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(int))
|
|
#define MemCopyChar(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(char))
|
|
|
|
#define MemMove(_type, _dest, _src, _count) memmove(_dest, _src, _count * sizeof(_type))
|
|
#define MemMoveFloat(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(float))
|
|
#define MemMoveInt(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(int))
|
|
#define MemMoveChar(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(char))
|
|
|
|
#define MemSet(_type, _dest, _val, _count) memset(_dest, _val, _count * sizeof(_type))
|
|
#define MemSetFloat(_dest, _val, _count) memset(_dest, _val, _count * sizeof(float))
|
|
#define MemSetInt(_dest, _val, _count) memset(_dest, _val, _count * sizeof(int))
|
|
#define MemSetChar(_dest, _val, _count) memset(_dest, _val, _count * sizeof(char))
|
|
|
|
class ZAlloc
|
|
{
|
|
public:
|
|
/*
|
|
static public Alloc
|
|
Allocation function. Gives back an allocated array of at least _size in length.
|
|
|
|
@param _size - the size of the block of type T
|
|
|
|
@return (T*) - an array of T of at least _size in length
|
|
*/
|
|
template <class T>
|
|
static T* Alloc(size_t _size);
|
|
|
|
/*
|
|
public static Free
|
|
|
|
Free function.
|
|
|
|
@param _data - an array allocated through the use of Alloc
|
|
|
|
@return (void)
|
|
*/
|
|
template <class T>
|
|
static void Free(T *_data);
|
|
};
|
|
|
|
template <class T>
|
|
T* ZAlloc::Alloc(size_t _size)
|
|
{
|
|
return new (std::nothrow) T[_size];
|
|
}
|
|
|
|
template <class T>
|
|
void ZAlloc::Free(T *_data)
|
|
{
|
|
delete [] _data;
|
|
}
|
|
|
|
#endif
|
|
|