Make possible for the user to use a custom pool memory allocator

This commit is contained in:
Daniel Chappuis 2018-09-26 18:25:31 +02:00
parent dfa9a31a9e
commit b3cd791146
12 changed files with 51 additions and 36 deletions

View File

@ -6,6 +6,7 @@
- Make possible for the user to get vertices, normals and triangle indices of a ConcaveMeshShape - Make possible for the user to get vertices, normals and triangle indices of a ConcaveMeshShape
- Make possible for the user to get vertices and height values of the HeightFieldShape - Make possible for the user to get vertices and height values of the HeightFieldShape
- Make possible for the user to use a custom single frame and pool memory allocator
### Fixed ### Fixed

View File

@ -148,7 +148,7 @@ SET (REACTPHYSICS3D_HEADERS
"src/mathematics/Vector3.h" "src/mathematics/Vector3.h"
"src/mathematics/Ray.h" "src/mathematics/Ray.h"
"src/memory/MemoryAllocator.h" "src/memory/MemoryAllocator.h"
"src/memory/PoolAllocator.h" "src/memory/DefaultPoolAllocator.h"
"src/memory/DefaultSingleFrameAllocator.h" "src/memory/DefaultSingleFrameAllocator.h"
"src/memory/DefaultAllocator.h" "src/memory/DefaultAllocator.h"
"src/memory/MemoryManager.h" "src/memory/MemoryManager.h"
@ -226,7 +226,7 @@ SET (REACTPHYSICS3D_SOURCES
"src/mathematics/Transform.cpp" "src/mathematics/Transform.cpp"
"src/mathematics/Vector2.cpp" "src/mathematics/Vector2.cpp"
"src/mathematics/Vector3.cpp" "src/mathematics/Vector3.cpp"
"src/memory/PoolAllocator.cpp" "src/memory/DefaultPoolAllocator.cpp"
"src/memory/DefaultSingleFrameAllocator.cpp" "src/memory/DefaultSingleFrameAllocator.cpp"
"src/memory/MemoryManager.cpp" "src/memory/MemoryManager.cpp"
"src/utils/Profiler.cpp" "src/utils/Profiler.cpp"

View File

@ -42,7 +42,7 @@ class ProxyShape;
class CollisionWorld; class CollisionWorld;
class CollisionShape; class CollisionShape;
struct RaycastInfo; struct RaycastInfo;
class PoolAllocator; class DefaultPoolAllocator;
class Profiler; class Profiler;
/// Enumeration for the type of a body /// Enumeration for the type of a body

View File

@ -38,7 +38,7 @@ class ContactManifoldInfo;
struct ContactPointInfo; struct ContactPointInfo;
class CollisionBody; class CollisionBody;
class ContactPoint; class ContactPoint;
class PoolAllocator; class DefaultPoolAllocator;
// Structure ContactManifoldListElement // Structure ContactManifoldListElement
/** /**

View File

@ -40,7 +40,7 @@ BroadPhaseAlgorithm::BroadPhaseAlgorithm(CollisionDetection& collisionDetection)
mNbPotentialPairs(0), mNbAllocatedPotentialPairs(8), mNbPotentialPairs(0), mNbAllocatedPotentialPairs(8),
mCollisionDetection(collisionDetection) { mCollisionDetection(collisionDetection) {
PoolAllocator& poolAllocator = collisionDetection.getMemoryManager().getPoolAllocator(); MemoryAllocator& poolAllocator = collisionDetection.getMemoryManager().getPoolAllocator();
// Allocate memory for the array of potential overlapping pairs // Allocate memory for the array of potential overlapping pairs
mPotentialPairs = static_cast<BroadPhasePair*>(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair))); mPotentialPairs = static_cast<BroadPhasePair*>(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)));
@ -58,7 +58,7 @@ BroadPhaseAlgorithm::BroadPhaseAlgorithm(CollisionDetection& collisionDetection)
BroadPhaseAlgorithm::~BroadPhaseAlgorithm() { BroadPhaseAlgorithm::~BroadPhaseAlgorithm() {
// Get the memory pool allocatory // Get the memory pool allocatory
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); MemoryAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
// Release the memory for the array of potential overlapping pairs // Release the memory for the array of potential overlapping pairs
poolAllocator.release(mPotentialPairs, mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); poolAllocator.release(mPotentialPairs, mNbAllocatedPotentialPairs * sizeof(BroadPhasePair));
@ -234,7 +234,7 @@ void BroadPhaseAlgorithm::computeOverlappingPairs(MemoryManager& memoryManager)
// number of overlapping pairs // number of overlapping pairs
if (mNbPotentialPairs < mNbAllocatedPotentialPairs / 4 && mNbPotentialPairs > 8) { if (mNbPotentialPairs < mNbAllocatedPotentialPairs / 4 && mNbPotentialPairs > 8) {
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); MemoryAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
// Reduce the number of allocated potential overlapping pairs // Reduce the number of allocated potential overlapping pairs
BroadPhasePair* oldPairs = mPotentialPairs; BroadPhasePair* oldPairs = mPotentialPairs;
@ -260,7 +260,7 @@ void BroadPhaseAlgorithm::addOverlappingNodes(int referenceNodeId, const LinkedL
// If we need to allocate more memory for the array of potential overlapping pairs // If we need to allocate more memory for the array of potential overlapping pairs
if (mNbPotentialPairs == mNbAllocatedPotentialPairs) { if (mNbPotentialPairs == mNbAllocatedPotentialPairs) {
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); MemoryAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
// Allocate more memory for the array of potential pairs // Allocate more memory for the array of potential pairs
BroadPhasePair* oldPairs = mPotentialPairs; BroadPhasePair* oldPairs = mPotentialPairs;

View File

@ -34,7 +34,7 @@ namespace reactphysics3d {
class CollisionDetection; class CollisionDetection;
class Body; class Body;
class ContactManifoldInfo; class ContactManifoldInfo;
class PoolAllocator; class DefaultPoolAllocator;
class OverlappingPair; class OverlappingPair;
struct NarrowPhaseInfo; struct NarrowPhaseInfo;
struct ContactPointInfo; struct ContactPointInfo;

View File

@ -35,7 +35,7 @@ namespace reactphysics3d {
// Declarations // Declarations
class Profiler; class Profiler;
class PoolAllocator; class DefaultPoolAllocator;
class AABB; class AABB;
class Transform; class Transform;
struct Ray; struct Ray;

View File

@ -24,7 +24,7 @@
********************************************************************************/ ********************************************************************************/
// Libraries // Libraries
#include "PoolAllocator.h" #include "DefaultPoolAllocator.h"
#include "MemoryManager.h" #include "MemoryManager.h"
#include <cstdlib> #include <cstdlib>
#include <cassert> #include <cassert>
@ -32,12 +32,12 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Initialization of static variables // Initialization of static variables
bool PoolAllocator::isMapSizeToHeadIndexInitialized = false; bool DefaultPoolAllocator::isMapSizeToHeadIndexInitialized = false;
size_t PoolAllocator::mUnitSizes[NB_HEAPS]; size_t DefaultPoolAllocator::mUnitSizes[NB_HEAPS];
int PoolAllocator::mMapSizeToHeapIndex[MAX_UNIT_SIZE + 1]; int DefaultPoolAllocator::mMapSizeToHeapIndex[MAX_UNIT_SIZE + 1];
// Constructor // Constructor
PoolAllocator::PoolAllocator() { DefaultPoolAllocator::DefaultPoolAllocator() {
// Allocate some memory to manage the blocks // Allocate some memory to manage the blocks
mNbAllocatedMemoryBlocks = 64; mNbAllocatedMemoryBlocks = 64;
@ -79,7 +79,7 @@ PoolAllocator::PoolAllocator() {
} }
// Destructor // Destructor
PoolAllocator::~PoolAllocator() { DefaultPoolAllocator::~DefaultPoolAllocator() {
// Release the memory allocated for each block // Release the memory allocated for each block
for (uint i=0; i<mNbCurrentMemoryBlocks; i++) { for (uint i=0; i<mNbCurrentMemoryBlocks; i++) {
@ -98,7 +98,7 @@ PoolAllocator::~PoolAllocator() {
// Allocate memory of a given size (in bytes) and return a pointer to the // Allocate memory of a given size (in bytes) and return a pointer to the
// allocated memory. // allocated memory.
void* PoolAllocator::allocate(size_t size) { void* DefaultPoolAllocator::allocate(size_t size) {
// We cannot allocate zero bytes // We cannot allocate zero bytes
if (size == 0) return nullptr; if (size == 0) return nullptr;
@ -171,7 +171,7 @@ void* PoolAllocator::allocate(size_t size) {
} }
// Release previously allocated memory. // Release previously allocated memory.
void PoolAllocator::release(void* pointer, size_t size) { void DefaultPoolAllocator::release(void* pointer, size_t size) {
// Cannot release a 0-byte allocated memory // Cannot release a 0-byte allocated memory
if (size == 0) return; if (size == 0) return;

View File

@ -33,14 +33,14 @@
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
// Class PoolAllocator // Class DefaultPoolAllocator
/** /**
* This class is used to efficiently allocate memory on the heap. * This class is used to efficiently allocate memory on the heap.
* It allows us to allocate small blocks of memory (smaller or equal to 1024 bytes) * It allows us to allocate small blocks of memory (smaller or equal to 1024 bytes)
* efficiently. This implementation is inspired by the small block allocator * efficiently. This implementation is inspired by the small block allocator
* described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp * described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp
*/ */
class PoolAllocator : public MemoryAllocator { class DefaultPoolAllocator : public MemoryAllocator {
private : private :
@ -126,13 +126,13 @@ class PoolAllocator : public MemoryAllocator {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
PoolAllocator(); DefaultPoolAllocator();
/// Destructor /// Destructor
virtual ~PoolAllocator() override; virtual ~DefaultPoolAllocator() override;
/// Assignment operator /// Assignment operator
PoolAllocator& operator=(PoolAllocator& allocator) = default; DefaultPoolAllocator& operator=(DefaultPoolAllocator& allocator) = default;
/// Allocate memory of a given size (in bytes) and return a pointer to the /// Allocate memory of a given size (in bytes) and return a pointer to the
/// allocated memory. /// allocated memory.

View File

@ -33,8 +33,8 @@ using namespace reactphysics3d;
// Constructor // Constructor
DefaultSingleFrameAllocator::DefaultSingleFrameAllocator() DefaultSingleFrameAllocator::DefaultSingleFrameAllocator()
: mTotalSizeBytes(INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES), : mBaseMemoryAllocator(&MemoryManager::getBaseAllocator()),
mBaseMemoryAllocator(&MemoryManager::getBaseAllocator()), mTotalSizeBytes(INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES),
mCurrentOffset(0), mNbFramesTooMuchAllocated(0), mNeedToAllocatedMore(false) { mCurrentOffset(0), mNbFramesTooMuchAllocated(0), mNeedToAllocatedMore(false) {
// Allocate a whole block of memory at the beginning // Allocate a whole block of memory at the beginning

View File

@ -31,6 +31,8 @@ using namespace reactphysics3d;
// Static variables // Static variables
DefaultAllocator MemoryManager::mDefaultAllocator; DefaultAllocator MemoryManager::mDefaultAllocator;
DefaultSingleFrameAllocator MemoryManager::mDefaultSingleFrameAllocator; DefaultSingleFrameAllocator MemoryManager::mDefaultSingleFrameAllocator;
DefaultPoolAllocator MemoryManager::mDefaultPoolAllocator;
MemoryAllocator* MemoryManager::mBaseAllocator = &mDefaultAllocator; MemoryAllocator* MemoryManager::mBaseAllocator = &mDefaultAllocator;
MemoryAllocator* MemoryManager::mPoolAllocator = &mDefaultPoolAllocator;
SingleFrameAllocator* MemoryManager::mSingleFrameAllocator = &mDefaultSingleFrameAllocator; SingleFrameAllocator* MemoryManager::mSingleFrameAllocator = &mDefaultSingleFrameAllocator;

View File

@ -28,7 +28,8 @@
// Libraries // Libraries
#include "memory/DefaultAllocator.h" #include "memory/DefaultAllocator.h"
#include "memory/PoolAllocator.h" #include "memory/DefaultPoolAllocator.h"
#include "memory/MemoryAllocator.h"
#include "memory/DefaultSingleFrameAllocator.h" #include "memory/DefaultSingleFrameAllocator.h"
/// Namespace ReactPhysics3D /// Namespace ReactPhysics3D
@ -49,9 +50,12 @@ class MemoryManager {
/// Default malloc/free memory allocator /// Default malloc/free memory allocator
static DefaultAllocator mDefaultAllocator; static DefaultAllocator mDefaultAllocator;
/// Default malloc/free memory allocator /// Default single frame memory allocator
static DefaultSingleFrameAllocator mDefaultSingleFrameAllocator; static DefaultSingleFrameAllocator mDefaultSingleFrameAllocator;
/// Default pool memory allocator
static DefaultPoolAllocator mDefaultPoolAllocator;
/// Pointer to the base memory allocator to use /// Pointer to the base memory allocator to use
static MemoryAllocator* mBaseAllocator; static MemoryAllocator* mBaseAllocator;
@ -59,7 +63,7 @@ class MemoryManager {
static SingleFrameAllocator* mSingleFrameAllocator; static SingleFrameAllocator* mSingleFrameAllocator;
/// Memory pool allocator /// Memory pool allocator
PoolAllocator mPoolAllocator; static MemoryAllocator* mPoolAllocator;
public: public:
@ -83,7 +87,7 @@ class MemoryManager {
void release(AllocationType allocationType, void* pointer, size_t size); void release(AllocationType allocationType, void* pointer, size_t size);
/// Return the pool allocator /// Return the pool allocator
PoolAllocator& getPoolAllocator(); MemoryAllocator& getPoolAllocator();
/// Return the single frame stack allocator /// Return the single frame stack allocator
SingleFrameAllocator& getSingleFrameAllocator(); SingleFrameAllocator& getSingleFrameAllocator();
@ -95,7 +99,10 @@ class MemoryManager {
static void setBaseAllocator(MemoryAllocator* memoryAllocator); static void setBaseAllocator(MemoryAllocator* memoryAllocator);
/// Set the single frame memory allocator /// Set the single frame memory allocator
static void setSingleFrameAllocator(SingleFrameAllocator* memoryAllocator); static void setSingleFrameAllocator(SingleFrameAllocator* singleFrameAllocator);
/// Set the pool memory allocator
static void setPoolAllocator(MemoryAllocator* poolAllocator);
/// Reset the single frame allocator /// Reset the single frame allocator
void resetFrameAllocator(); void resetFrameAllocator();
@ -106,7 +113,7 @@ inline void* MemoryManager::allocate(AllocationType allocationType, size_t size)
switch (allocationType) { switch (allocationType) {
case AllocationType::Base: return mBaseAllocator->allocate(size); case AllocationType::Base: return mBaseAllocator->allocate(size);
case AllocationType::Pool: return mPoolAllocator.allocate(size); case AllocationType::Pool: return mPoolAllocator->allocate(size);
case AllocationType::Frame: return mSingleFrameAllocator->allocate(size); case AllocationType::Frame: return mSingleFrameAllocator->allocate(size);
} }
@ -118,14 +125,14 @@ inline void MemoryManager::release(AllocationType allocationType, void* pointer,
switch (allocationType) { switch (allocationType) {
case AllocationType::Base: mBaseAllocator->release(pointer, size); break; case AllocationType::Base: mBaseAllocator->release(pointer, size); break;
case AllocationType::Pool: mPoolAllocator.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;
} }
} }
// Return the pool allocator // Return the pool allocator
inline PoolAllocator& MemoryManager::getPoolAllocator() { inline MemoryAllocator& MemoryManager::getPoolAllocator() {
return mPoolAllocator; return *mPoolAllocator;
} }
// Return the single frame stack allocator // Return the single frame stack allocator
@ -144,8 +151,13 @@ inline void MemoryManager::setBaseAllocator(MemoryAllocator* baseAllocator) {
} }
// Set the base memory allocator // Set the base memory allocator
inline void MemoryManager::setSingleFrameAllocator(SingleFrameAllocator* allocator) { inline void MemoryManager::setSingleFrameAllocator(SingleFrameAllocator* singleFrameAllocator) {
mSingleFrameAllocator = allocator; mSingleFrameAllocator = singleFrameAllocator;
}
// Set the pool memory allocator
inline void MemoryManager::setPoolAllocator(MemoryAllocator* poolAllocator) {
mPoolAllocator = poolAllocator;
} }
// Reset the single frame allocator // Reset the single frame allocator