You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/CryCommon/CryPool/Inspector.h

204 lines
8.2 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYPOOL_INSPECTOR_H
#define CRYINCLUDE_CRYPOOL_INSPECTOR_H
#pragma once
namespace NCryPoolAlloc
{
template<class TAllocator>
class CInspector
: public TAllocator
{
enum
{
EITableSize = 30
};
size_t m_Allocations[EITableSize];
size_t m_Alignment[EITableSize];
char m_LogFileName[1024];
size_t m_AllocCount;
size_t m_FreeCount;
size_t m_ResizeCount;
size_t m_FailAllocCount;
size_t m_FailFreeCount;
size_t m_FailResizeCount;
void WriteOut(const char* pFileName, uint32 Stack, const char* pFormat, ...) const
{
/*
if(!pFileName)
{
if(!*m_LogFileName)
return;
pFileName = m_LogFileName;
}
FILE* File = fopen(pFileName,"a");
if(File)
{
char Buffer[1024];
for(uint32 a=0;a<Stack;a++)
Buffer[a]=' ';
va_list args;
va_start(args,pFormat);
vsprintf(Buffer+Stack,pFormat,args);
fwrite(Buffer,1,strlen(Buffer),File);
fclose(File);
va_end(args);
}
*/
}
size_t Bit(size_t C) const
{
size_t Count = 0;
C >>= 1;
while (C)
{
Count++;
C >>= 1;
}
return Count >= EITableSize ? EITableSize - 1 : Count;
}
public:
CInspector()
{
for (size_t a = 0; a < EITableSize; a++)
{
m_Allocations[a] = m_Alignment[a] = 0;
}
m_LogFileName[0] = 0;
m_AllocCount = 0;
m_FreeCount = 0;
m_ResizeCount = 0;
m_FailAllocCount = 0;
m_FailFreeCount = 0;
m_FailResizeCount = 0;
}
bool LogFileName(const char* pFileName)
{
const size_t Size = strlen(pFileName) + 1;
if (Size > sizeof(m_LogFileName))
{
m_LogFileName[0] = 0;
return false;
}
memcpy(m_LogFileName, pFileName, Size);
WriteOut(0, "[log start]\n");
return true;
}
void SaveStats(const char* pFileName) const
{
WriteOut(pFileName, 0, "stats:\n");
WriteOut(pFileName, 1, "Counter calls|fails\n");
WriteOut(pFileName, 2, "Alloc: %6d|%6d\n", m_AllocCount, m_FailAllocCount);
WriteOut(pFileName, 2, "Free: %6d|%6d\n", m_FreeCount, m_FailFreeCount);
WriteOut(pFileName, 2, "Resize:%6d|%6d\n", m_ResizeCount, m_FailResizeCount);
WriteOut(pFileName, 1, "Allocations:\n");
for (size_t a = 0; a < EITableSize; a++)
{
WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Allocations[a]);
}
WriteOut(pFileName, 1, "Alignment:\n");
for (size_t a = 0; a < EITableSize; a++)
{
WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Alignment[a]);
}
}
template<class T>
ILINE T Allocate(size_t Size, size_t Align = 1)
{
m_AllocCount++;
m_Allocations[Bit(Size)]++;
m_Alignment[Bit(Align)]++;
T pData = TAllocator::template Allocate<T>(Size, Align);
WriteOut(0, 0, "[A|%d|%d|%d]", (int)pData, Size, Align);
if (!pData)
{
m_FailAllocCount++;
WriteOut(0, 0, "[failed]", Size, Align);
}
return pData;
}
template<class T>
ILINE bool Free(T pData, bool ForceBoundsCheck = false)
{
m_FreeCount++;
const bool Ret = TAllocator::Free(pData, ForceBoundsCheck);
WriteOut(0, 0, "[F|%d|%d|%d]", (int)pData, (int)ForceBoundsCheck, (int)Ret);
m_FailFreeCount += !Ret;
return Ret;
}
//template<class T>
//ILINE bool Free(T pData)
// {
// m_FreeCount++;
// const bool Ret = TAllocator::Free(pData);
// WriteOut(0,0,"[F|%d|%d|%d]",(int)pData,(int)-1,(int)Ret);
// m_FailFreeCount+=!Ret;
// return Ret;
// }
template<class T>
ILINE bool Resize(T** pData, size_t Size, size_t Alignment)
{
m_ResizeCount++;
const bool Ret = TAllocator::Resize(pData, Size, Alignment);
WriteOut(0, 0, "[R|%d|%d|%d]", (int)*pData, (int)-1, (int)Ret);
m_FailResizeCount += !Ret;
return Ret;
}
template<class T>
ILINE size_t FindBiggest(const T* pItem)
{
size_t Biggest = 0;
while (pItem)
{
if (pItem->IsFree() && pItem->MemSize() > Biggest)
{
Biggest = pItem->MemSize();
}
pItem = pItem->Next();
}
return Biggest;
}
ILINE size_t BiggestFreeBlock()
{
return FindBiggest(TAllocator::m_Items.First());
}
ILINE uint8* FirstItem()
{
return TAllocator::m_Items.First()->Data();
}
};
}
#endif // CRYINCLUDE_CRYPOOL_INSPECTOR_H