#include <dali/internal/common/fixed-size-memory-pool.h>
// INTERNAL HEADERS
-#include <dali/public-api/dali-core.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/public-api/common/dali-common.h>
namespace Dali
{
{
void* blockMemory; ///< The allocated memory from which allocations can be made
Block* nextBlock; ///< The next block in the linked list
-
+#ifdef DEBUG_ENABLED
+ SizeType mBlockSize; ///< Size of the block in bytes
+#endif
/**
* @brief Construct a new block with given size
*
*/
Block( SizeType size )
: nextBlock( NULL )
+#ifdef DEBUG_ENABLED
+ ,mBlockSize( size )
+#endif
{
blockMemory = ::operator new( size );
DALI_ASSERT_ALWAYS( blockMemory && "Out of memory" );
{
::operator delete( blockMemory );
}
+
+ private:
+ // Undefined
+ Block( const Block& block );
+
+ // Undefined
+ Block& operator=( const Block& block );
};
/**
* @brief Constructor
*/
Impl( SizeType fixedSize, SizeType initialCapacity, SizeType maximumBlockCapacity )
- : mFixedSize( fixedSize ),
+ : mMutex(),
+ mFixedSize( fixedSize ),
mMemoryBlocks( initialCapacity * mFixedSize ),
mMaximumBlockCapacity( maximumBlockCapacity ),
mCurrentBlock( &mMemoryBlocks ),
mCurrentBlockSize = 0;
}
+#ifdef DEBUG_ENABLED
+
+ /**
+ * @brief check the memory being free'd exists inside the memory pool
+ * @param[in] memory address of object to remove
+ */
+ void CheckMemoryIsInsidePool( const void* const memory )
+ {
+ bool inRange = false;
+ const Block* block = &mMemoryBlocks;
+
+ while( block )
+ {
+ const void* const endOfBlock = reinterpret_cast<char *>( block->blockMemory )+ block->mBlockSize;
+
+ if( ( memory >= block->blockMemory ) && ( memory < (endOfBlock) ) )
+ {
+ inRange = true;
+ break;
+ }
+ block = block->nextBlock;
+ }
+ DALI_ASSERT_DEBUG( inRange && "Freeing memory that does not exist in memory pool" );
+ }
+#endif
+
+ Mutex mMutex; ///< Mutex for thread-safe allocation and deallocation
SizeType mFixedSize; ///< The size of each allocation in bytes
}
// Placement new the object in block memory
- unsigned char* objectAddress = static_cast< unsigned char* >( mImpl->mCurrentBlock->blockMemory );
+ uint8_t* objectAddress = static_cast< uint8_t* >( mImpl->mCurrentBlock->blockMemory );
objectAddress += mImpl->mCurrentBlockSize * mImpl->mFixedSize;
mImpl->mCurrentBlockSize++;
void FixedSizeMemoryPool::Free( void* memory )
{
+#ifdef DEBUG_ENABLED
+ mImpl->CheckMemoryIsInsidePool( memory );
+#endif
+
// Add memory to head of deleted objects list. Store next address in the same memory space as the old object.
*( reinterpret_cast< void** >( memory ) ) = mImpl->mDeletedObjects;
mImpl->mDeletedObjects = memory;
}
+void* FixedSizeMemoryPool::AllocateThreadSafe()
+{
+ Mutex::ScopedLock lock( mImpl->mMutex );
+ return Allocate();
+}
+
+void FixedSizeMemoryPool::FreeThreadSafe( void* memory )
+{
+ Mutex::ScopedLock lock( mImpl->mMutex );
+ Free( memory );
+}
+
+
} // namespace Internal
} // namespace Dali