📄 hxalloc.cpp
字号:
}
}
if (m_bEstimateFreeListSize)
{
m_uiCurrentHistoryIndex = ++m_uiCurrentHistoryIndex % m_uiPoolHistoryDepth;
m_puiBufferUseHistory[m_uiCurrentHistoryIndex] = m_MemBlockMap.GetCount();
}
WriteRuntimeStats();
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
return(pRetVal);
}
CHXMemoryBlock* CHXMemoryAllocator::PacketPtrToPacketObj(UCHAR * memPtr)
{
HX_ASSERT(memPtr);
// find the instance pointer for the CHXMemoryBlock that
// ownes this memory buffer and AddRef the block
CHXMemoryBlock * pMemBlock = NULL;
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
m_MemBlockMap.Lookup(memPtr, (void *&)pMemBlock);
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
return(pMemBlock);
}
UINT16 CHXMemoryAllocator::AddRefPacketPtr(UCHAR * memPtr)
{
HX_ASSERT(memPtr);
// find the instance pointer for the CHXMemoryBlock that
// ownes this memory buffer and AddRef the block
CHXMemoryBlock * pMemBlock;
UINT16 uiRetVal = 0;
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
if (m_MemBlockMap.Lookup(memPtr, (void *&)pMemBlock))
{
uiRetVal = (UINT16)pMemBlock->AddRef();
}
else
{
// shouldn't AddRef memory that doesn't exist...
HX_ASSERT(FALSE);
}
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
return(uiRetVal);
}
UINT16 CHXMemoryAllocator::ReleasePacketPtr(UCHAR * memPtr)
{
HX_ASSERT(memPtr);
// find the instance pointer for the CHXMemoryBlock that
// ownes this memory buffer and AddRef the block
UINT16 uiRetVal = 0;
if (!memPtr)
{
return(uiRetVal);
}
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
CHXMemoryBlock * pMemBlock;
if (m_MemBlockMap.Lookup(memPtr, (void *&)pMemBlock))
{
uiRetVal = (UINT16)pMemBlock->Release();
}
else
{
// shouldn't AddRef memory that doesn't exist...
HX_ASSERT(FALSE);
}
WriteRuntimeStats();
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
return(uiRetVal);
}
#ifdef XXXJEFFA_DEBUG
UINT32 g_NextLogTime = 0;
#endif
void CHXMemoryAllocator::NotifyFreeBlock(CHXMemoryBlock * pMemBlock)
{
HX_ASSERT(pMemBlock);
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
// Remove the memory from the map since it's not going
// to be considered valid anymore
m_MemBlockMap.RemoveKey(pMemBlock->GetSampleBase());
UINT32 uiMaxRecentlyUsed = 0;
if (m_bEstimateFreeListSize)
{
for (UINT32 i = 0; i < m_uiPoolHistoryDepth; i++)
{
if (m_puiBufferUseHistory[i] > uiMaxRecentlyUsed)
{
uiMaxRecentlyUsed = m_puiBufferUseHistory[i];
}
}
}
// as long as this block is the right size we will
// recycle it
if (m_uSize == pMemBlock->GetLength()
&& ( (m_freeList.GetCount() < (int) m_Count) &&
(m_bEstimateFreeListSize ? m_AllocCount <= uiMaxRecentlyUsed + 1 : TRUE)
)
)
{
BOOL bAddToTail = (HX_GET_BETTERTICKCOUNT() & 0x01) ? TRUE : FALSE;
if (bAddToTail)
{
m_freeList.AddTail(pMemBlock);
}
else
{
m_freeList.AddHead(pMemBlock);
}
#ifdef XXXJEFFA_DEBUG
if (!HXMM_ATINTERRUPT() && HX_GET_TICKCOUNT() > g_NextLogTime)
{
FILE* pFile = fopen("Boot Drive:Desktop Folder:log.txt", "a+t");
if (pFile)
{
fprintf(pFile, "%p\t%d\t%d\t%lu\n", this, m_freeList.GetCount(), m_uSize, (m_freeList.GetCount()*m_uSize));
fclose(pFile);
}
g_NextLogTime = HX_GET_TICKCOUNT() + 10000UL;
}
#endif
}
else
{
// if it doesn't go on the free block list
// then delete it
pMemBlock->Free();
delete pMemBlock;
m_AllocCount--;
}
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
}
///////////////////////////////////////////////////////////////////////////////
// CHXBufferMemoryAllocator Implementation
///////////////////////////////////////////////////////////////////////////////
HX_RESULT
CHXBufferMemoryAllocator::QueryInterface(HX_IID iid, void** ppvObj)
{
HX_ASSERT(ppvObj);
// Do dynamic Cast
if (iid == IID_IHX20MemoryAllocator)
{
*ppvObj = (IHX20MemoryAllocator *)this;
}
else if (iid == IID_IHXUnknown)
{
*ppvObj = (IHXUnknown *)this;
}
else
{
*ppvObj = NULL;
}
// Do lifetime control
if (*ppvObj != NULL)
{
((IHXUnknown *)*ppvObj)->AddRef();
}
return( (*ppvObj != NULL)?(HX_NO_ERROR):(HX_NO_INTERFACE));
}
ULONG32 CHXBufferMemoryAllocator::AddRef()
{
HX_ASSERT(this);
return InterlockedIncrement(&m_ref);
}
ULONG32 CHXBufferMemoryAllocator::Release()
{
HX_ASSERT(this);
HX_ASSERT(m_ref != 0);
if(InterlockedDecrement(&m_ref) == 0)
{
delete this;
return 0;
}
return m_ref;
}
struct BufferBlock
{
IHXBuffer* m_pBuf;
INT32 m_lRefCount;
};
CHXBufferMemoryAllocator::CHXBufferMemoryAllocator(BOOL bThreadSafe)
: m_Count(0)
, m_uSize(0)
, m_ref(0)
#ifndef WIN32
, m_pMutex(NULL)
#else // WIN32
, m_bThreadSafe(bThreadSafe)
#endif // WIN32
{
#ifdef WIN32
if (m_bThreadSafe) InitializeCriticalSection(&m_critsec);
#else // WIN32
if (bThreadSafe)
{
#ifdef THREADS_SUPPORTED
HXMutex::MakeMutex(m_pMutex);
#else // THREADS_SUPPORTED
HXMutex::MakeStubMutex(m_pMutex);
#endif // THREADS_SUPPORTED
}
#endif // WIN32
}
CHXBufferMemoryAllocator::~CHXBufferMemoryAllocator()
{
// cleanup memory left by the user in the map
POSITION currentMapNode = m_BufMap.GetStartPosition();
BufferBlock* pBufBlock;
UCHAR* memPtr;
// we should find the map empty.
HX_ASSERT(m_BufMap.IsEmpty());
while(!m_BufMap.IsEmpty())
{
m_BufMap.GetNextAssoc(currentMapNode, (void *&)memPtr, (void *&)pBufBlock);
if (pBufBlock != NULL)
{
HX_ASSERT(FALSE);
HX_RELEASE(pBufBlock->m_pBuf);
HX_DELETE(pBufBlock);
}
}
#ifdef WIN32
if (m_bThreadSafe) DeleteCriticalSection(&m_critsec);
#else // WIN32
HX_DELETE(m_pMutex);
#endif // WIN32
}
HX_RESULT CHXBufferMemoryAllocator::SetProperties(HX20ALLOCPROPS* pRequest,
HX20ALLOCPROPS* pActual)
{
pActual->uBufferSize = m_uSize = pRequest->uBufferSize;
pActual->nNumBuffers = m_Count = pRequest->nNumBuffers;
return HXR_OK;
}
HX_RESULT CHXBufferMemoryAllocator::GetProperties(HX20ALLOCPROPS* pProps)
{
pProps->uBufferSize = m_uSize;
pProps->nNumBuffers = m_Count;
return HXR_OK;
}
UCHAR* CHXBufferMemoryAllocator::GetPacketBuffer(IHXUnknown ** pPacketBuffer)
{
// XXXX JHUG we are not keeping a free list, should do that...
HX_ASSERT_VALID_PTR(this);
HX_ASSERT_VALID_PTR(pPacketBuffer);
UCHAR * pRetVal = NULL;
*pPacketBuffer = NULL;
if (m_uSize > 0)
{
BufferBlock* pBufBlock = new BufferBlock();
IHXBuffer* pBuffer = new CHXBuffer();
HX_ASSERT(pBufBlock && pBuffer);
if (pBuffer && pBufBlock)
{
pBuffer->AddRef();
pBufBlock->m_pBuf = pBuffer;
pBufBlock->m_lRefCount = 1;
if (SUCCEEDED(pBuffer->SetSize(m_uSize)))
{
pRetVal = pBuffer->GetBuffer();
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
m_BufMap.SetAt(pRetVal, pBufBlock);
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
*pPacketBuffer = (IHXUnknown *) pBuffer;
}
else
{
HX_RELEASE(pBuffer);
}
}
else
{
HX_DELETE(pBufBlock);
HX_RELEASE(pBuffer);
}
}
return(pRetVal);
}
UCHAR* CHXBufferMemoryAllocator::AddBuffer(IHXBuffer* pBuf)
{
HX_ASSERT(pBuf);
UCHAR* pMem = NULL;
if (pBuf)
{
BufferBlock* pBufBlock = new BufferBlock;
HX_ASSERT(pBufBlock);
if (pBufBlock)
{
pBuf->AddRef();
pBufBlock->m_pBuf = pBuf;
pBufBlock->m_lRefCount = 1;
pMem = pBuf->GetBuffer();
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
m_BufMap.SetAt(pMem, pBufBlock);
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
}
}
return pMem;
}
UINT16 CHXBufferMemoryAllocator::AddRefPacketPtr(UCHAR * memPtr)
{
HX_ASSERT(memPtr);
BufferBlock* pBlock = NULL;
UINT16 uiRetVal = 0;
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
if (m_BufMap.Lookup(memPtr, (void *&)pBlock))
{
uiRetVal = (UINT16)++(pBlock->m_lRefCount);
}
else
{
// shouldn't AddRef memory that doesn't exist...
HX_ASSERT(FALSE);
}
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
return uiRetVal;
}
UINT16 CHXBufferMemoryAllocator::ReleasePacketPtr(UCHAR * memPtr)
{
UINT16 uiRetVal = 0;
HX_ASSERT(memPtr);
if (!memPtr)
{
return uiRetVal;
}
#ifdef WIN32
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Lock();
}
#endif // WIN32
BufferBlock* pBlock = NULL;
if (m_BufMap.Lookup(memPtr, (void *&)pBlock))
{
uiRetVal = (UINT16)--(pBlock->m_lRefCount);
if (pBlock->m_lRefCount == 0)
{
HX_RELEASE(pBlock->m_pBuf);
HX_DELETE(pBlock);
m_BufMap.RemoveKey(memPtr);
}
}
else
{
// shouldn't Release memory that doesn't exist...
HX_ASSERT(FALSE);
}
#ifdef WIN32
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
#else // WIN32
if (m_pMutex)
{
m_pMutex->Unlock();
}
#endif // WIN32
return uiRetVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -