diff --git a/CMakeLists.txt b/CMakeLists.txt index 389fadcf..9793b4b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,7 +149,7 @@ SET (REACTPHYSICS3D_HEADERS "src/mathematics/Ray.h" "src/memory/MemoryAllocator.h" "src/memory/PoolAllocator.h" - "src/memory/SingleFrameAllocator.h" + "src/memory/DefaultSingleFrameAllocator.h" "src/memory/DefaultAllocator.h" "src/memory/MemoryManager.h" "src/containers/Stack.h" @@ -227,7 +227,7 @@ SET (REACTPHYSICS3D_SOURCES "src/mathematics/Vector2.cpp" "src/mathematics/Vector3.cpp" "src/memory/PoolAllocator.cpp" - "src/memory/SingleFrameAllocator.cpp" + "src/memory/DefaultSingleFrameAllocator.cpp" "src/memory/MemoryManager.cpp" "src/utils/Profiler.cpp" "src/utils/Logger.cpp" diff --git a/src/memory/SingleFrameAllocator.cpp b/src/memory/DefaultSingleFrameAllocator.cpp similarity index 81% rename from src/memory/SingleFrameAllocator.cpp rename to src/memory/DefaultSingleFrameAllocator.cpp index 6ffe924b..62c586e7 100644 --- a/src/memory/SingleFrameAllocator.cpp +++ b/src/memory/DefaultSingleFrameAllocator.cpp @@ -24,7 +24,7 @@ ********************************************************************************/ // Libraries -#include "SingleFrameAllocator.h" +#include "DefaultSingleFrameAllocator.h" #include "MemoryManager.h" #include #include @@ -32,26 +32,27 @@ using namespace reactphysics3d; // Constructor -SingleFrameAllocator::SingleFrameAllocator() +DefaultSingleFrameAllocator::DefaultSingleFrameAllocator() : mTotalSizeBytes(INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES), + mBaseMemoryAllocator(&MemoryManager::getBaseAllocator()), mCurrentOffset(0), mNbFramesTooMuchAllocated(0), mNeedToAllocatedMore(false) { // Allocate a whole block of memory at the beginning - mMemoryBufferStart = static_cast(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes)); + mMemoryBufferStart = static_cast(mBaseMemoryAllocator->allocate(mTotalSizeBytes)); assert(mMemoryBufferStart != nullptr); } // Destructor -SingleFrameAllocator::~SingleFrameAllocator() { +DefaultSingleFrameAllocator::~DefaultSingleFrameAllocator() { // Release the memory allocated at the beginning - MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes); + mBaseMemoryAllocator->release(mMemoryBufferStart, mTotalSizeBytes); } // Allocate memory of a given size (in bytes) and return a pointer to the // allocated memory. -void* SingleFrameAllocator::allocate(size_t size) { +void* DefaultSingleFrameAllocator::allocate(size_t size) { // Check that there is enough remaining memory in the buffer if (mCurrentOffset + size > mTotalSizeBytes) { @@ -60,7 +61,7 @@ void* SingleFrameAllocator::allocate(size_t size) { mNeedToAllocatedMore = true; // Return default memory allocation - return MemoryManager::getBaseAllocator().allocate(size); + return mBaseMemoryAllocator->allocate(size); } // Next available memory location @@ -74,19 +75,19 @@ void* SingleFrameAllocator::allocate(size_t size) { } // Release previously allocated memory. -void SingleFrameAllocator::release(void* pointer, size_t size) { +void DefaultSingleFrameAllocator::release(void* pointer, size_t size) { // If allocated memory is not within the single frame allocation range char* p = static_cast(pointer); if (p < mMemoryBufferStart || p > mMemoryBufferStart + mTotalSizeBytes) { // Use default deallocation - MemoryManager::getBaseAllocator().release(pointer, size); + mBaseMemoryAllocator->release(pointer, size); } } // Reset the marker of the current allocated memory -void SingleFrameAllocator::reset() { +void DefaultSingleFrameAllocator::reset() { // If too much memory is allocated if (mCurrentOffset < mTotalSizeBytes / 2) { @@ -96,14 +97,14 @@ void SingleFrameAllocator::reset() { if (mNbFramesTooMuchAllocated > NB_FRAMES_UNTIL_SHRINK) { // Release the memory allocated at the beginning - MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes); + mBaseMemoryAllocator->release(mMemoryBufferStart, mTotalSizeBytes); // Divide the total memory to allocate by two mTotalSizeBytes /= 2; if (mTotalSizeBytes == 0) mTotalSizeBytes = 1; // Allocate a whole block of memory at the beginning - mMemoryBufferStart = static_cast(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes)); + mMemoryBufferStart = static_cast(mBaseMemoryAllocator->allocate(mTotalSizeBytes)); assert(mMemoryBufferStart != nullptr); mNbFramesTooMuchAllocated = 0; @@ -117,13 +118,13 @@ void SingleFrameAllocator::reset() { if (mNeedToAllocatedMore) { // Release the memory allocated at the beginning - MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes); + mBaseMemoryAllocator->release(mMemoryBufferStart, mTotalSizeBytes); // Multiply the total memory to allocate by two mTotalSizeBytes *= 2; // Allocate a whole block of memory at the beginning - mMemoryBufferStart = static_cast(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes)); + mMemoryBufferStart = static_cast(mBaseMemoryAllocator->allocate(mTotalSizeBytes)); assert(mMemoryBufferStart != nullptr); mNeedToAllocatedMore = false; diff --git a/src/memory/SingleFrameAllocator.h b/src/memory/DefaultSingleFrameAllocator.h similarity index 87% rename from src/memory/SingleFrameAllocator.h rename to src/memory/DefaultSingleFrameAllocator.h index 599c0b65..65641129 100644 --- a/src/memory/SingleFrameAllocator.h +++ b/src/memory/DefaultSingleFrameAllocator.h @@ -33,12 +33,12 @@ /// ReactPhysics3D namespace namespace reactphysics3d { -// Class SingleFrameAllocator +// Class DefaultSingleFrameAllocator /** * This class represent a memory allocator used to efficiently allocate * memory on the heap that is used during a single frame. */ -class SingleFrameAllocator : public MemoryAllocator { +class DefaultSingleFrameAllocator : public SingleFrameAllocator { private : @@ -49,9 +49,11 @@ class SingleFrameAllocator : public MemoryAllocator { static const int NB_FRAMES_UNTIL_SHRINK = 120; /// Initial size (in bytes) of the single frame allocator - size_t INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES = 1048576; // 1Mb + static const size_t INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES = 1048576; // 1Mb // -------------------- Attributes -------------------- // + /// Cached memory allocator used on construction + MemoryAllocator* mBaseMemoryAllocator; /// Total size (in bytes) of memory of the allocator size_t mTotalSizeBytes; @@ -74,13 +76,13 @@ class SingleFrameAllocator : public MemoryAllocator { // -------------------- Methods -------------------- // /// Constructor - SingleFrameAllocator(); + DefaultSingleFrameAllocator(); /// Destructor - virtual ~SingleFrameAllocator() override; + virtual ~DefaultSingleFrameAllocator() override; /// Assignment operator - SingleFrameAllocator& operator=(SingleFrameAllocator& allocator) = default; + DefaultSingleFrameAllocator& operator=(DefaultSingleFrameAllocator& allocator) = default; /// Allocate memory of a given size (in bytes) virtual void* allocate(size_t size) override; @@ -89,7 +91,7 @@ class SingleFrameAllocator : public MemoryAllocator { virtual void release(void* pointer, size_t size) override; /// Reset the marker of the current allocated memory - virtual void reset(); + virtual void reset() override; }; } diff --git a/src/memory/MemoryAllocator.h b/src/memory/MemoryAllocator.h index 9811387b..cc0df8de 100644 --- a/src/memory/MemoryAllocator.h +++ b/src/memory/MemoryAllocator.h @@ -57,6 +57,33 @@ class MemoryAllocator { virtual void release(void* pointer, size_t size)=0; }; +/** + * Abstract class with the basic interface of all single frames memory allocators + */ +class SingleFrameAllocator : public MemoryAllocator{ + + public: + + /// Constructor + SingleFrameAllocator() = default; + + /// Destructor + virtual ~SingleFrameAllocator() override = default; + + /// Assignment operator + SingleFrameAllocator& operator=(SingleFrameAllocator& allocator) = default; + + /// Allocate memory of a given size (in bytes) and return a pointer to the + /// allocated memory. + virtual void* allocate(size_t size) override =0; + + /// Release previously allocated memory. + virtual void release(void* pointer, size_t size) override =0; + + /// Reset the marker of the current allocated memory + virtual void reset()=0; +}; + } #endif diff --git a/src/memory/MemoryManager.cpp b/src/memory/MemoryManager.cpp index 7dc80543..e74422ef 100644 --- a/src/memory/MemoryManager.cpp +++ b/src/memory/MemoryManager.cpp @@ -30,5 +30,7 @@ using namespace reactphysics3d; // Static variables DefaultAllocator MemoryManager::mDefaultAllocator; +DefaultSingleFrameAllocator MemoryManager::mDefaultSingleFrameAllocator; MemoryAllocator* MemoryManager::mBaseAllocator = &mDefaultAllocator; +SingleFrameAllocator* MemoryManager::mSingleFrameAllocator = &mDefaultSingleFrameAllocator; diff --git a/src/memory/MemoryManager.h b/src/memory/MemoryManager.h index 65797218..9ed6f6b4 100644 --- a/src/memory/MemoryManager.h +++ b/src/memory/MemoryManager.h @@ -29,7 +29,7 @@ // Libraries #include "memory/DefaultAllocator.h" #include "memory/PoolAllocator.h" -#include "memory/SingleFrameAllocator.h" +#include "memory/DefaultSingleFrameAllocator.h" /// Namespace ReactPhysics3D namespace reactphysics3d { @@ -45,19 +45,22 @@ class MemoryAllocator; class MemoryManager { private: - + /// Default malloc/free memory allocator static DefaultAllocator mDefaultAllocator; + + /// Default malloc/free memory allocator + static DefaultSingleFrameAllocator mDefaultSingleFrameAllocator; /// Pointer to the base memory allocator to use static MemoryAllocator* mBaseAllocator; + /// Single frame stack allocator + static SingleFrameAllocator* mSingleFrameAllocator; + /// Memory pool allocator PoolAllocator mPoolAllocator; - /// Single frame stack allocator - SingleFrameAllocator mSingleFrameAllocator; - public: /// Memory allocation types @@ -87,10 +90,13 @@ class MemoryManager { /// Return the base memory allocator static MemoryAllocator& getBaseAllocator(); - + /// Set the base memory allocator static void setBaseAllocator(MemoryAllocator* memoryAllocator); + /// Set the single frame memory allocator + static void setSingleFrameAllocator(SingleFrameAllocator* memoryAllocator); + /// Reset the single frame allocator void resetFrameAllocator(); }; @@ -101,7 +107,7 @@ inline void* MemoryManager::allocate(AllocationType allocationType, size_t size) switch (allocationType) { case AllocationType::Base: return mBaseAllocator->allocate(size); case AllocationType::Pool: return mPoolAllocator.allocate(size); - case AllocationType::Frame: return mSingleFrameAllocator.allocate(size); + case AllocationType::Frame: return mSingleFrameAllocator->allocate(size); } return nullptr; @@ -113,7 +119,7 @@ inline void MemoryManager::release(AllocationType allocationType, void* pointer, switch (allocationType) { case AllocationType::Base: mBaseAllocator->release(pointer, size); break; case AllocationType::Pool: mPoolAllocator.release(pointer, size); break; - case AllocationType::Frame: mSingleFrameAllocator.release(pointer, size); break; + case AllocationType::Frame: mSingleFrameAllocator->release(pointer, size); break; } } @@ -124,7 +130,7 @@ inline PoolAllocator& MemoryManager::getPoolAllocator() { // Return the single frame stack allocator inline SingleFrameAllocator& MemoryManager::getSingleFrameAllocator() { - return mSingleFrameAllocator; + return *mSingleFrameAllocator; } // Return the base memory allocator @@ -137,9 +143,14 @@ inline void MemoryManager::setBaseAllocator(MemoryAllocator* baseAllocator) { mBaseAllocator = baseAllocator; } +// Set the base memory allocator +inline void MemoryManager::setSingleFrameAllocator(SingleFrameAllocator* allocator) { + mSingleFrameAllocator = allocator; +} + // Reset the single frame allocator inline void MemoryManager::resetFrameAllocator() { - mSingleFrameAllocator.reset(); + mSingleFrameAllocator->reset(); } }