Files
mir_server/sdk/utils/BufferAllocatorEx.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

494 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <Tick.h>
#include "Lock.h"
#include "ShareUtil.h"
#include "BufferAllocator.h"
static const DWORD dwBufferFreeTick = 30 * 1000;//标记为释放的的内存块的延时销毁时间
CBufferAllocator::CBufferAllocator()
{
m_pLastSmallBuffer = NULL;
m_pLastMiddleBuffer = NULL;
m_pLastLargeBuffer = NULL;
m_pLastSuperBuffer = NULL;
#ifdef _BUFFER_TRACE
m_pLastAllocedBuffer = NULL;
#endif
m_dwAllocedSmallSize = 0;
m_dwAllocedMiddleSize = 0;
m_dwAllocedLargeSize = 0;
m_dwAllocedSuperSize = 0;
m_dwFreedSmallSize = 0;
m_dwFreedMiddleSize = 0;
m_dwFreedLargeSize = 0;
m_dwFreedSuperSize = 0;
//InitializeCriticalSection( &m_BufferLock );
}
CBufferAllocator::~CBufferAllocator()
{
PBUFFER pBuffer, pPrevBuffer;
pBuffer = m_pLastSmallBuffer;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
free( pBuffer );
pBuffer = pPrevBuffer;
}
pBuffer = m_pLastMiddleBuffer;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
free( pBuffer );
pBuffer = pPrevBuffer;
}
pBuffer = m_pLastLargeBuffer;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
free( pBuffer );
pBuffer = pPrevBuffer;
}
pBuffer = m_pLastSuperBuffer;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
free( pBuffer );
pBuffer = pPrevBuffer;
}
#ifdef _BUFFER_TRACE
pBuffer = m_pLastAllocedBuffer;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
TRACE( _T("%s(%d) : 申请的内存块没有释放pointer Addr=%d\n"), pBuffer->al.lpFile, pBuffer->al.nLine,(INT_PTR)pBuffer );
free( pBuffer );
pBuffer = pPrevBuffer;
//Assert(FALSE);//有内存泄漏,提醒
}
#endif
//DeleteCriticalSection( &m_BufferLock );
}
#ifndef _BUFFER_TRACE
PVOID CBufferAllocator::AllocBuffer(size_t dwSize)
#else
PVOID CBufferAllocator::_AllocBuffer(size_t dwSize, const char *lpFile, int nLine)
#endif
{
if(m_dwFreedSuperSize >100000000 || m_dwFreedLargeSize > 100000000)
{
CheckFreeBuffers(true);
}
PBUFFER pBuffer, pPrev, pResult = NULL;
//EnterCriticalSection( &m_BufferLock );
m_BufferLock.Lock();
if ( dwSize <= SmallBufferSize )
{
if ( m_pLastSmallBuffer )
{
pResult = m_pLastSmallBuffer;
m_pLastSmallBuffer = pResult->pPrevBuffer;
pResult->pPrevBuffer = NULL;
m_dwFreedSmallSize -= SmallBufferSize;
}
else
{
#ifdef _BUFFER_TRACE
pResult = (PBUFFER)malloc( SmallBufferSize + sizeof(*pResult) + sizeof(INT) );
#else
pResult = (PBUFFER)malloc( SmallBufferSize + sizeof(*pResult) );
#endif
pResult->dwSize = SmallBufferSize;
pResult->pPrevBuffer = NULL;
#ifdef _BUFFER_TRACE
pResult->boUsing = FALSE;
pResult->pNextBuffer = NULL;
#endif
}
m_dwAllocedSmallSize += SmallBufferSize;
}
else if ( dwSize <= MiddleBufferSize )
{
if ( m_pLastMiddleBuffer )
{
pResult = m_pLastMiddleBuffer;
m_pLastMiddleBuffer = pResult->pPrevBuffer;
pResult->pPrevBuffer = NULL;
m_dwFreedMiddleSize -= MiddleBufferSize;
}
else
{
#ifdef _BUFFER_TRACE
pResult = (PBUFFER)malloc( MiddleBufferSize + sizeof(*pResult) + sizeof(INT) );
#else
pResult = (PBUFFER)malloc( MiddleBufferSize + sizeof(*pResult) );
#endif
pResult->dwSize = MiddleBufferSize;
pResult->pPrevBuffer = NULL;
#ifdef _BUFFER_TRACE
pResult->boUsing = FALSE;
pResult->pNextBuffer = NULL;
#endif
}
m_dwAllocedMiddleSize += MiddleBufferSize;
}
else if ( dwSize <= LargeBufferSize )
{
if ( m_pLastLargeBuffer )
{
pResult = m_pLastLargeBuffer;
m_pLastLargeBuffer = pResult->pPrevBuffer;
pResult->pPrevBuffer = NULL;
m_dwFreedLargeSize -= LargeBufferSize;
}
else
{
#ifdef _BUFFER_TRACE
pResult = (PBUFFER)malloc( LargeBufferSize + sizeof(*pResult) + sizeof(INT) );
#else
pResult = (PBUFFER)malloc( LargeBufferSize + sizeof(*pResult) );
#endif
pResult->dwSize = LargeBufferSize;
pResult->pPrevBuffer = NULL;
#ifdef _BUFFER_TRACE
pResult->boUsing = FALSE;
pResult->pNextBuffer = NULL;
#endif
}
m_dwAllocedLargeSize += LargeBufferSize;
}
else
{
pPrev = NULL;
pBuffer = m_pLastSuperBuffer;
while ( pBuffer )
{
if ( pBuffer->dwSize >= dwSize )
{
pResult = pBuffer;
#ifdef _BUFFER_TRACE
Assert( !pResult->boUsing );
#endif
if ( pResult == m_pLastSuperBuffer )
{
m_pLastSuperBuffer = pResult->pPrevBuffer;
pResult->pPrevBuffer = NULL;
}
else if ( pPrev )
{
pPrev->pPrevBuffer = pResult->pPrevBuffer;
pResult->pPrevBuffer = NULL;
}
m_dwFreedSuperSize -= pResult->dwSize;
break;
}
pPrev = pBuffer;
pBuffer = pBuffer->pPrevBuffer;
}
if ( !pResult )
{
dwSize = (dwSize + 511) & (~511);
#ifdef _BUFFER_TRACE
pResult = (PBUFFER)malloc( dwSize + sizeof(*pResult) + sizeof(INT) );
#else
pResult = (PBUFFER)malloc( dwSize + sizeof(*pResult) );
#endif
pResult->dwSize = dwSize;
pResult->pPrevBuffer = NULL;
#ifdef _BUFFER_TRACE
pResult->boUsing = FALSE;
pResult->pNextBuffer = NULL;
#endif
}
m_dwAllocedSuperSize += pResult->dwSize;
}
#ifdef _BUFFER_TRACE
if ( pResult )
{
Assert( !pResult->boUsing );
pResult->boUsing = TRUE;
pResult->al.lpFile = lpFile;
pResult->al.nLine = nLine;
pResult->fl.lpFile = NULL;
pResult->fl.nLine = 0;
pResult->dwFreeTick = 0;
*((PINT)((char*)(pResult + 1) + pResult->dwSize)) = 0xCC55EE33;
if ( m_pLastAllocedBuffer ) m_pLastAllocedBuffer->pNextBuffer = pResult;
pResult->pPrevBuffer = m_pLastAllocedBuffer;
pResult->pNextBuffer = NULL;
m_pLastAllocedBuffer = pResult;
}
#endif
//LeaveCriticalSection( &m_BufferLock );
m_BufferLock.Unlock();
return pResult ? pResult + 1 : NULL;
}
#ifndef _BUFFER_TRACE
PVOID CBufferAllocator::ReallocBuffer(PVOID ptr, size_t dwNewSize)
#else
PVOID CBufferAllocator::_ReallocBuffer(PVOID ptr, size_t dwNewSize, const char* lpFile, int nLine)
#endif
{
if (dwNewSize == 0)
{
FreeBuffer(ptr);
return NULL;
}
PBUFFER pBuffer;
if (ptr)
{
pBuffer = ((PBUFFER)ptr) - 1;
if (dwNewSize <= pBuffer->dwSize)
return ptr;
}
PVOID pResult;
#ifndef _BUFFER_TRACE
pResult = AllocBuffer(dwNewSize);
if (ptr)
{
memcpy(pResult, ptr, pBuffer->dwSize);
FreeBuffer(ptr);
}
#else
pResult = _AllocBuffer(dwNewSize, lpFile, NULL);
if (ptr)
{
memcpy(pResult, ptr, pBuffer->dwSize);
_FreeBuffer(ptr, lpFile, NULL);
}
#endif
return pResult;
}
#ifndef _BUFFER_TRACE
VOID CBufferAllocator::FreeBuffer(PVOID ptr)
#else
VOID CBufferAllocator::_FreeBuffer(PVOID ptr, const char* lpFile, int nLine)
#endif
{
PBUFFER pBuffer;
if (!ptr) return;
pBuffer = ((PBUFFER)ptr) - 1;
//EnterCriticalSection( &m_BufferLock );
m_BufferLock.Lock();
#ifdef _BUFFER_TRACE
if ( !pBuffer->boUsing )
{
//TRACE( _T(__FUNCTION__)_T(" 试图释放已经被标记为释放的内存块(%X,大小:%d),申请位置:%s(%d),释放位置:%s(%d)\n"),
// pBuffer, pBuffer->dwSize, pBuffer->al.lpFile, pBuffer->al.nLine,
// pBuffer->fl.lpFile, pBuffer->fl.nLine );
OutputMsg(rmError, _T(" %s试图释放已经被标记为释放的内存块(%X,大小:%d),申请位置:%s(%d),释放位置:%s(%d)\n"),
__FUNCTION__,pBuffer, pBuffer->dwSize, pBuffer->al.lpFile, pBuffer->al.nLine,
pBuffer->fl.lpFile, pBuffer->fl.nLine );
}
Assert( pBuffer->boUsing );
pBuffer->boUsing = FALSE;
Assert(*((PINT)((char*)(pBuffer + 1) + pBuffer->dwSize)) == 0xCC55EE33);
if ( pBuffer->pPrevBuffer )
pBuffer->pPrevBuffer->pNextBuffer = pBuffer->pNextBuffer;
if ( pBuffer->pNextBuffer )
pBuffer->pNextBuffer->pPrevBuffer = pBuffer->pPrevBuffer;
if ( pBuffer == m_pLastAllocedBuffer )
m_pLastAllocedBuffer = pBuffer->pPrevBuffer;
pBuffer->pPrevBuffer = NULL;
pBuffer->pNextBuffer = NULL;
pBuffer->fl.lpFile = lpFile;
pBuffer->fl.nLine = nLine;
#endif
pBuffer->dwFreeTick = _getTickCount() + dwBufferFreeTick;
if ( pBuffer->dwSize == SmallBufferSize )
{
pBuffer->pPrevBuffer = m_pLastSmallBuffer;
m_pLastSmallBuffer = pBuffer;
m_dwAllocedSmallSize -= SmallBufferSize;
m_dwFreedSmallSize += SmallBufferSize;
}
else if ( pBuffer->dwSize == MiddleBufferSize )
{
pBuffer->pPrevBuffer = m_pLastMiddleBuffer;
m_pLastMiddleBuffer = pBuffer;
m_dwAllocedMiddleSize -= MiddleBufferSize;
m_dwFreedMiddleSize += MiddleBufferSize;
}
else if ( pBuffer->dwSize == LargeBufferSize )
{
pBuffer->pPrevBuffer = m_pLastLargeBuffer;
m_pLastLargeBuffer = pBuffer;
m_dwAllocedLargeSize -= LargeBufferSize;
m_dwFreedLargeSize += LargeBufferSize;
}
else
{
pBuffer->pPrevBuffer = m_pLastSuperBuffer;
m_pLastSuperBuffer = pBuffer;
m_dwAllocedSuperSize -= pBuffer->dwSize;
m_dwFreedSuperSize += pBuffer->dwSize;
}
//LeaveCriticalSection( &m_BufferLock );
m_BufferLock.Unlock();
}
VOID CBufferAllocator::GetMemoryInfo(CBufferAllocator::PALLOCATPR_MEMORY_INFOR pMemoryInfo)
{
pMemoryInfo->SmallBuffer.dwAllocSize = m_dwAllocedSmallSize;
pMemoryInfo->SmallBuffer.dwFreeSize = m_dwFreedSmallSize;
pMemoryInfo->MiddleBuffer.dwAllocSize = m_dwAllocedMiddleSize;
pMemoryInfo->MiddleBuffer.dwFreeSize = m_dwFreedMiddleSize;
pMemoryInfo->LargeBuffer.dwAllocSize = m_dwAllocedLargeSize;
pMemoryInfo->LargeBuffer.dwFreeSize = m_dwFreedLargeSize;
pMemoryInfo->SuperBuffer.dwAllocSize = m_dwAllocedSuperSize;
pMemoryInfo->SuperBuffer.dwFreeSize = m_dwFreedSuperSize;
}
VOID CBufferAllocator::CheckFreeBuffers(bool bIgnoreInterval)
{
PBUFFER pBuffer, pPrevBuffer, pLastBuffer;
LONGLONG dwTick = _getTickCount();
//EnterCriticalSection( &m_BufferLock );
m_BufferLock.Lock();
pBuffer = m_pLastSmallBuffer;
pLastBuffer = NULL;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
if (bIgnoreInterval || dwTick >= pBuffer->dwFreeTick)
{
if ( pBuffer == m_pLastSmallBuffer )
m_pLastSmallBuffer = pPrevBuffer;
if ( pLastBuffer )
pLastBuffer->pPrevBuffer = pPrevBuffer;
m_dwFreedSmallSize -= pBuffer->dwSize;
free( pBuffer );
}
else pLastBuffer = pBuffer;
pBuffer = pPrevBuffer;
}
pBuffer = m_pLastMiddleBuffer;
pLastBuffer = NULL;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
if (bIgnoreInterval || dwTick >= pBuffer->dwFreeTick)
{
if ( pBuffer == m_pLastMiddleBuffer )
m_pLastMiddleBuffer = pPrevBuffer;
if ( pLastBuffer )
pLastBuffer->pPrevBuffer = pPrevBuffer;
m_dwFreedMiddleSize -= pBuffer->dwSize;
free( pBuffer );
}
else pLastBuffer = pBuffer;
pBuffer = pPrevBuffer;
}
pBuffer = m_pLastLargeBuffer;
pLastBuffer = NULL;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
if (bIgnoreInterval || dwTick >= pBuffer->dwFreeTick)
{
if ( pBuffer == m_pLastLargeBuffer )
m_pLastLargeBuffer = pPrevBuffer;
if ( pLastBuffer )
pLastBuffer->pPrevBuffer = pPrevBuffer;
m_dwFreedLargeSize -= pBuffer->dwSize;
free( pBuffer );
}
else pLastBuffer = pBuffer;
pBuffer = pPrevBuffer;
}
pBuffer = m_pLastSuperBuffer;
pLastBuffer = NULL;
while ( pBuffer )
{
pPrevBuffer = pBuffer->pPrevBuffer;
if (bIgnoreInterval || dwTick >= pBuffer->dwFreeTick)
{
if ( pBuffer == m_pLastSuperBuffer )
m_pLastSuperBuffer = pPrevBuffer;
if ( pLastBuffer )
pLastBuffer->pPrevBuffer = pPrevBuffer;
m_dwFreedSuperSize -= pBuffer->dwSize;
free( pBuffer );
}
else pLastBuffer = pBuffer;
pBuffer = pPrevBuffer;
}
//LeaveCriticalSection( &m_BufferLock );
m_BufferLock.Unlock();
}
#ifdef _BUFFER_TRACE
DataBuffer::DataBuffer(CBufferAllocator *pAllocator, size_t dwSize, const char *_FILE, const int _LINE)
#else
DataBuffer::DataBuffer(CBufferAllocator *pAllocator, size_t dwSize)
#endif
{
m_pAllocator = pAllocator;
m_dwSize = dwSize;
#ifdef _BUFFER_TRACE
pData = (char*)pAllocator->_AllocBuffer(dwSize, _FILE, _LINE);
#else
pData = (char*)pAllocator->AllocBuffer(dwSize);
#endif
ptr = pReadPtr = pData;
pEnd = pData + dwSize;
}
DataBuffer::~DataBuffer()
{
m_pAllocator->FreeBuffer( pData );
}