⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxalloc.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
	}

        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 + -