text: #include "UnlockedMemoryPool.h"
  using namespace fpnn;
  /*===============================================================================
    FUNCTION DEFINITIONS: General Size Fixed Memory Pool Functions
    =============================================================================== */
  /*===========================================================================
  
  FUNCTION: TMemoryPool::GainNode
  
  DESCRIPTION:
  Gain the available node from memory buffer.
  
  PARAMETERS:
  Mutex [in] - The mutex belonged to a specified sub pool.
  ppRecycleLinkHead [in] - The pointer point to the head pointer of recycle list belonged to a specified sub pool.
  ppActiveLinkHead [in] - The pointer point to the head pointer of active list belonged to a specified sub pool.
  
  RETURN VALUE:
  T* - Succeed;
  NULL - Failed.
  ===========================================================================*/
  MemoryData*  UnlockedMemoryPool::GainNode()
  {
  	MemoryData* pPointer = NULL;
  	{
  		//std::lock_guard<std::mutex> lck (_mutex);
  		pPointer = _recycleLink;
  		if (!pPointer)
  			return NULL;
  
  		_recycleLink = _recycleLink->Next;
  		if (_recycleLink)
  			_recycleLink->Pre = NULL;
  
  		//-- Active Link
  		pPointer->Pre = NULL;
  		pPointer->Next = _activeLink;
  		if (_activeLink)
  			_activeLink->Pre = pPointer;
  		_activeLink = pPointer;
  
  		_usedCount += 1;
  		_freeCount -= 1;
  
  	}
  
  	//new((K*)pPointer) K;  //-- just Object Pool doing.
  	return pPointer;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::RecycleNode
  
  DESCRIPTION:
  Recycle memory block, and hang it over the recycle list. 
  
  PARAMETERS:
  Mutex [in] - The mutex belonged to a specified sub pool.
  ppRecycleLinkHead [in] - The pointer point to the head pointer of recycle list belonged to a specified sub pool.
  ppActiveLinkHead [in] - The pointer point to the head pointer of active list belonged to a specified sub pool.
  ppNode [in] - The block will be recycled.
  
  RETURN VALUE:
  None
  ===========================================================================*/
  void UnlockedMemoryPool::RecycleNode(MemoryData* memoryData)
  {
  	//((K*)(*ppNode))->~K();  //-- just Object Pool doing.
  
  	//std::lock_guard<std::mutex> lck (_mutex);
  	{
  		//-- Active Link
  		if (memoryData->Pre)
  			memoryData->Pre->Next = memoryData->Next;
  		else
  		{
  			// *ppNode is the pActiveLinkHead.
  			_activeLink = memoryData->Next;
  		}
  		if (memoryData->Next)
  			memoryData->Next->Pre = memoryData->Pre;
  
  		//-- Recycle Link
  		memoryData->Pre = NULL;
  		memoryData->Next = _recycleLink;
  		if (_recycleLink)
  			_recycleLink->Pre = memoryData;
  		_recycleLink = memoryData;
  
  		_usedCount -= 1;
  		_freeCount += 1;
  	}
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::RecycleOverdraftNode
  
  DESCRIPTION:
  Recycle overdraft memory block. 
  
  PARAMETERS:
  Mutex [in] - The mutex belonged to a specified sub pool.
  ppActiveLinkHead [in] - The pointer point to the head pointer of active overdraft list belonged to a specified sub pool.
  ppNode [in] - The block will be recovered.
  
  RETURN VALUE:
  None
  ===========================================================================*/
  void UnlockedMemoryPool::RecycleOverdraftNode(MemoryData* memoryData)
  {
  	//((K*)(*ppNode))->~K();  //-- just Object Pool doing.
  
  	//std::lock_guard<std::mutex> lck (_mutex);
  	{
  		//-- Active Link
  		if (memoryData->Pre)
  			memoryData->Pre->Next = memoryData->Next;
  		else
  		{
  			// *ppNode is the pActiveOverdraftLinkHead.
  			_activeOverdraftLink = memoryData->Next;
  		}
  		if (memoryData->Next)
  			memoryData->Next->Pre = memoryData->Pre;
  
  		_overdraftCount -= 1;
  		_totalCount -= 1;
  
  		free(memoryData);
  	}
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::AppendNode
  
  DESCRIPTION:
  Append new memory blocks in the pool.
  
  PARAMETERS:
  Mutex [in] - The mutex belonged to a specified sub pool.
  ppRecycleLinkHead [in] - The pointer point to the head pointer of recycle list belonged to a specified sub pool.
  ulNumber [in] - The number of memory blocks which will be added.
  
  RETURN VALUE:
  E_SUCCESS - Succeed;
  E_MEMORY_POOL__APPEND_MEMORY - Append Failed;
  ===========================================================================*/
  bool UnlockedMemoryPool::AppendNode(int32_t needBlocks)
  {
  	MemoryData*			pTempHeader = NULL;
  	MemoryData*			pPointer = NULL;
  
  	int32_t count = 0;
  	for (; count < needBlocks; count++)
  	{
  		pPointer = (MemoryData*)malloc(sizeof(MemoryData) + _blockSize);
  		if (!pPointer)
  			break;
  
  		pPointer->Pre = NULL;
  		pPointer->Next = NULL;
  		pPointer->bOverdraft = NULL;
  
  		if (pTempHeader)
  		{
  			pTempHeader->Pre = pPointer;
  			pPointer->Next = pTempHeader;
  		}
  		pTempHeader = pPointer;
  	}
  
  	if (!pTempHeader)
  		return false;
  
  	{
  		//std::lock_guard<std::mutex> lck (_mutex);
  
  		_freeCount += count;
  		_totalCount += count;
  
  		pPointer = _recycleLink;
  		if (_recycleLink)
  		{
  			while (pPointer->Next)
  			{
  				pPointer = pPointer->Next;
  			}
  
  			pPointer->Next = pTempHeader;
  			pTempHeader->Pre = pPointer;
  		}
  		else
  			_recycleLink = pTempHeader;
  	}
  
  	return true;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::AppendOverdraftNode
  
  DESCRIPTION:
  Append the overdraft memory block in the pool.
  
  PARAMETERS:
  ppActiveOverdraftLinkHead [in] - The pointer point to the head pointer of active overdraft list belonged to a specified sub pool.
  
  RETURN VALUE:
  T* - Succeed;
  NULL - Failed.
  ===========================================================================*/
  MemoryData* UnlockedMemoryPool::AppendOverdraftNode()
  {
  	MemoryData* pPointer = NULL;
  
  	pPointer = (MemoryData*)malloc(sizeof(MemoryData) + _blockSize);
  
  	if (!pPointer)
  		return NULL;
  
  	pPointer->Pre = NULL;
  	pPointer->bOverdraft = this;
  
  	_overdraftCount += 1;
  	_totalCount += 1;
  
  	pPointer->Next = _activeOverdraftLink;
  	if (_activeOverdraftLink)
  		_activeOverdraftLink->Pre = pPointer;
  	_activeOverdraftLink = pPointer;
  
  	return pPointer;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::Append
  
  DESCRIPTION:
  Append new memory blocks in the pool.
  
  PARAMETERS:
  ulNumber [in] - The number of memory blocks which will be added.
  ppOverdraftNode [out] - Output the overdraft block after the memory pool catched the perfect restriction.
  
  RETURN VALUE:
  E_SUCCESS - Succeed;
  E_MEMORY_POOL__APPEND_MEMORY - Append Failed;
  E_MEMORY_POOL__CATCH_LIMITATION - The total number of memory blocks catched the maximum restriction of the pool.
  E_MEMORY_POOL__CATCH_PERFECT_LIMITATION - The number of standard memory blocks (not include the overdraft blocks) catched the perfect restriction of the pool.
  ===========================================================================*/
  bool UnlockedMemoryPool::Append(int32_t needBlocks, MemoryData** ppOverdraftNode)
  {
  	{
  		//std::lock_guard<std::mutex> lck (_mutex);
  
  		int32_t currentCount = _totalCount - _overdraftCount;
  		if (currentCount >= _perfectCount)
  		{
  			if (_maxCount != 0)
  			{
  				if (_maxCount == _totalCount)
  					return false;
  			}
  
  			*ppOverdraftNode = AppendOverdraftNode();
  
  			//if( *ppOverdraftNode )
  			//	new((K*)(*ppOverdraftNode)) K;	//-- just Object Pool doing.
  
  			return true;
  		}
  		else
  		{
  			int32_t	remainCount = _perfectCount - currentCount;
  			if( remainCount < needBlocks )
  				needBlocks = remainCount;
  		}
  	}
  
  	return AppendNode(needBlocks);
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::ReviseDataRelation
  
  DESCRIPTION:
  Revise the relation of data which are used to initialize the memory pool.
  
  PARAMETERS:
  ulInitNum [in] - The number for memory block allocation after the pool created.
  
  RETURN VALUE:
  None.
  ===========================================================================*/
  void UnlockedMemoryPool::ReviseDataRelation(int32_t initCount)
  {
  	if (_maxCount > 0)
  	{
  		if(_maxCount < initCount)
  			_maxCount = initCount;
  
  		if (_perfectCount > _maxCount)
  			_perfectCount = _maxCount;
  	}
  
  
  	if (_perfectCount < initCount)
  		_perfectCount = initCount;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::Init
  
  DESCRIPTION:
  Initialize the memory pool.
  
  PARAMETERS:
  ulInitNumber [in] - The number for memory block allocation after the pool created.
  ulMaxNumber [in] - The maximum number of blocks held by memory pool. If don't use the restriction, please let the value is ZERO.
  ulPerIncNumber [in] - The number of memory blocks appended in the appending operation.
  ulPerfectNumber [in] - The soft restriction. If the number of memory blocks beyond this restriction, the pool will return the 
  excess memories to the operating system rather than continue holding the blocks.
  
  RETURN VALUE:
  true - Succeed;
  false - Failed.   
  ===========================================================================*/
  bool UnlockedMemoryPool::init(size_t blockSize, int32_t initBlocks, int32_t perAppendBlocks, int32_t perfectBlocks, int32_t maxBlocks)
  {
  	if (_inited)
  		return true;
  
  	_blockSize = roundedSize(blockSize);
  	if (_blockSize < sizeof(void*))
  		return false;
  
  	_maxCount = maxBlocks;
  	_appendCount = perAppendBlocks;
  	_perfectCount = perfectBlocks;
  	ReviseDataRelation(initBlocks);
  
  	_inited = createPool(initBlocks);
  	return _inited;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::CreatePool
  
  DESCRIPTION:
  Create the memory pool.
  
  PARAMETERS:
  ulInitNumber [in] - The number for memory block allocation after the pool created.
  
  RETURN VALUE:
  true - Succeed;
  false - Failed.
  ===========================================================================*/
  bool UnlockedMemoryPool::createPool(int32_t initCount)
  {
  	//std::lock_guard<std::mutex> lck (_mutex);
  
  	if (_recycleLink || _activeLink)
  		clean();
  
  	int32_t count = 0;
  	for (; count < initCount; count++)
  	{
  		MemoryData* node = (MemoryData*)malloc(sizeof(MemoryData) + _blockSize);
  		if (node == NULL)
  		{
  			if (count == 0)
  				return false;
  			else
  				break;
  		}
  		node->Pre = NULL;
  		node->Next = _recycleLink;
  		if (_recycleLink)
  			_recycleLink->Pre = node;
  		_recycleLink = node;
  
  		node->bOverdraft = NULL;
  	}
  
  	_totalCount = count;
  	_freeCount = count;
  
  	return true;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::FreeOriginal
  
  DESCRIPTION:
  Free the memory pool without safeguard.
  
  PARAMETERS:
  None
  
  RETURN VALUE:
  None
  ===========================================================================*/
  void UnlockedMemoryPool::clean()
  {
  
  	MemoryData*		node = NULL;
  	while (_recycleLink)
  	{
  		node = _recycleLink;
  		_recycleLink = _recycleLink->Next;
  		free(node);
  	}
  	while (_activeLink)
  	{
  		node = _activeLink;
  		_activeLink = _activeLink->Next;
  		//((K*)node)->~K();  //-- just Object Pool doing.
  		free(node);
  	}
  	while (_activeOverdraftLink)
  	{
  		node = _activeOverdraftLink;
  		_activeOverdraftLink = _activeOverdraftLink->Next;
  		//((K*)node)->~K();  //-- just Object Pool doing.
  		free(node);
  	}
  
  	_recycleLink = NULL;
  	_activeLink = NULL;
  	_activeOverdraftLink = NULL;
  
  	_usedCount = 0;
  	_freeCount = 0;
  	_overdraftCount = 0;
  	_totalCount = 0;
  
  	_inited = false;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::Free
  
  DESCRIPTION:
  Free the memory pool with safeguard.
  
  PARAMETERS:
  None
  
  RETURN VALUE:
  None
  ===========================================================================*/
  void UnlockedMemoryPool::release()
  {
  	if (!_inited)
  		return;
  
  	clean();
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::Gain
  
  DESCRIPTION:
  Function series: Gain the memory block from buffer.
  
  PARAMETERS:
  None
  
  RETURN VALUE:
  NULL - Failed.
  Others - Succeed.
  ===========================================================================*/
  void* UnlockedMemoryPool::gain()
  {
  	if (_inited == false)
  		return NULL;
  
  	MemoryData* memoryData = GainNode();
  	if (memoryData)
  		return getMemoryPtr(memoryData);
  
  	if (Append(_appendCount, &memoryData))
  	{
  		if (memoryData)
  			return getMemoryPtr(memoryData);
  		else
  		{
  			memoryData = GainNode();
  			return getMemoryPtr(memoryData);
  		}
  	}
  	else
  		return NULL;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPool::Recycle
  
  DESCRIPTION:
  Function series: Recycle memory block, and hang it over the recycle list.
  
  PARAMETERS:
  pNode [in] - The block will be recycled.
  
  RETURN VALUE:
  None
  ===========================================================================*/
  void UnlockedMemoryPool::recycle(void** memory)
  {
  	if (!_inited || !memory || !(*memory))
  		return;
  
  	MemoryData* memoryData = getMemoryDataPtr(*memory);
  
  	if (memoryData->bOverdraft != NULL)
  		RecycleOverdraftNode(memoryData);
  	else
  		RecycleNode(memoryData);
  
  	*memory = NULL;
  }
  
  void UnlockedMemoryPool::recycle(void* & memory)
  {
  	if( !_inited || !memory )
  		return;
  
  	MemoryData* memoryData = getMemoryDataPtr(memory);
  
  	if (memoryData->bOverdraft != NULL)
  		RecycleOverdraftNode(memoryData);
  	else
  		RecycleNode(memoryData);
  
  	memory = NULL;
  }
  
  /*===========================================================================
  
  FUNCTION: TMemoryPoolLite::GetStatus
  
  DESCRIPTION:
  Get the memory blocks counters.
  
  PARAMETERS:
  strMPS [in] - The memory blocks counters unit.
  
  RETURN VALUE:
  None
  ===========================================================================*/
  inline void UnlockedMemoryPool::status(MemoryPoolStatus& mps)
  {
  	if (_inited)
  	{
  		//std::lock_guard<std::mutex> lck (_mutex);
  
  		mps.usedCount = _usedCount;
  		mps.freeCount = _freeCount;
  		mps.overdraftCount = _overdraftCount;
  		mps.totalUsedCount = _usedCount + _overdraftCount;
  		mps.totalCount = _totalCount;
  	}
  }
  