Continuation of the MemoryPool class
git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@441 92aac97c-a6ce-11dd-a772-7fcde58d38e6
This commit is contained in:
parent
10f46956b6
commit
0c7269d5ba
|
@ -28,6 +28,9 @@
|
|||
// Libraries
|
||||
#include "../constants.h"
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
@ -40,7 +43,7 @@ namespace reactphysics3d {
|
|||
and deallocation.
|
||||
-------------------------------------------------------------------
|
||||
*/
|
||||
template<typename T> // TODO : Check if we need to use a template here
|
||||
template<class T> // TODO : Check if we need to use a template here
|
||||
class MemoryPool {
|
||||
private:
|
||||
|
||||
|
@ -54,6 +57,8 @@ class MemoryPool {
|
|||
struct Unit* pAllocatedLinkedList; // Pointer to the linked list of allocated memory units
|
||||
struct Unit* pFreeLinkedList; // Pointer to the linked list of free memory units
|
||||
size_t memorySize; // Total allocated memory in the pool
|
||||
uint currentNbObjects; // Current number of objects in the pool
|
||||
const uint initNbAllocatedObjects; // Number of objects allocated at the beginning (used for reallocation)
|
||||
|
||||
public:
|
||||
MemoryPool(uint nbObjectsToAllocate) throw(std::bad_alloc); // Constructor
|
||||
|
@ -64,6 +69,108 @@ class MemoryPool {
|
|||
};
|
||||
|
||||
|
||||
// Constructor
|
||||
// Allocate a large block of memory in order to contain
|
||||
// a given number of object of the template type T
|
||||
template<class T>
|
||||
MemoryPool<T>::MemoryPool(uint nbObjectsToAllocate) throw(std::bad_alloc)
|
||||
: initNbAllocatedObjects(nbObjectsToAllocate), currentNbObjects(0) {
|
||||
pMemoryBlock = NULL;
|
||||
pAllocatedLinkedList = NULL;
|
||||
pFreeLinkedList = NULL;
|
||||
|
||||
// Compute the total memory size that need to be allocated
|
||||
memorySize = nbObjectsToAllocate * (sizeof(struct Unit) + sizeof(T));
|
||||
|
||||
// Allocate the whole memory block
|
||||
pMemoryBlock = malloc(memorySize);
|
||||
|
||||
// Check that the allocation didn't fail
|
||||
if (!pMemoryBlock) throw std::bad_alloc();
|
||||
|
||||
// For each allocated memory unit
|
||||
for (uint i=0; i<nbObjectsToAllocate; i++) {
|
||||
// Get the adress of a memory unit
|
||||
struct Unit* currentUnit = (struct Unit*)( (char*)pMemoryBlock + i * (sizeof(T) + sizeof(struct Unit)) );
|
||||
|
||||
currentUnit->pPrevious = NULL;
|
||||
currentUnit->pNext = pFreeLinkedList;
|
||||
|
||||
if (pFreeLinkedList) {
|
||||
pFreeLinkedList->pPrevious = currentUnit;
|
||||
}
|
||||
|
||||
pFreeLinkedList = currentUnit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
// Deallocate the block of memory that has been allocated previously
|
||||
template<class T>
|
||||
MemoryPool<T>::~MemoryPool() {
|
||||
// Release the whole memory block
|
||||
free(pMemoryBlock);
|
||||
}
|
||||
|
||||
// Return a pointer to an memory allocated location to store a new object
|
||||
// This method does not allocate memory because it has already been done at the
|
||||
// beginning but it returns a pointer to a location in the allocated block of
|
||||
// memory where a new object can be stored
|
||||
template<class T>
|
||||
void* MemoryPool<T>::allocateObject() {
|
||||
// If no memory unit is available in the current allocated memory block
|
||||
if (!pFreeLinkedList) {
|
||||
// TODO : REALLOCATE MEMORY HERE
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(pFreeLinkedList);
|
||||
struct Unit* currentUnit = pFreeLinkedList;
|
||||
pFreeLinkedList = currentUnit->pNext;
|
||||
if (pFreeLinkedList) {
|
||||
pFreeLinkedList->pPrevious = NULL;
|
||||
}
|
||||
|
||||
currentUnit->pNext = pAllocatedLinkedList;
|
||||
if (pAllocatedLinkedList) {
|
||||
pAllocatedLinkedList->pPrevious = currentUnit;
|
||||
}
|
||||
pAllocatedLinkedList = currentUnit;
|
||||
|
||||
currentNbObjects++;
|
||||
|
||||
// Return a pointer to the allocated memory unit
|
||||
return (void*)((char*)currentUnit + sizeof(struct Unit));
|
||||
}
|
||||
|
||||
// Tell the pool that an object doesn't need to be store in the pool anymore
|
||||
// This method does not deallocate memory because it will be done only at the
|
||||
// end but it informs the memory pool that an object that was stored in the heap
|
||||
// does not need to be stored anymore and therefore we can use the corresponding
|
||||
// location in the pool for another object
|
||||
template<class T>
|
||||
void MemoryPool<T>::freeObject(void* pObjectToFree) {
|
||||
// The pointer location must be inside the memory block
|
||||
assert(pMemoryBlock<pObjectToFree && pObjectToFree<(void*)((char*)pMemoryBlock + memorySize));
|
||||
|
||||
struct Unit* currentUnit = (struct Unit*)((char*)pObjectToFree - sizeof(struct Unit));
|
||||
pAllocatedLinkedList = currentUnit->pNext;
|
||||
if (pAllocatedLinkedList) {
|
||||
pAllocatedLinkedList->pPrevious = NULL;
|
||||
}
|
||||
|
||||
currentUnit->pNext = pFreeLinkedList;
|
||||
if (pFreeLinkedList) {
|
||||
pFreeLinkedList->pPrevious = currentUnit;
|
||||
}
|
||||
pFreeLinkedList = currentUnit;
|
||||
|
||||
currentNbObjects--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user