Make memory allocators thread safe
This commit is contained in:
parent
cfdab52573
commit
23041d474b
|
@ -52,12 +52,12 @@ class DefaultAllocator : public MemoryAllocator {
|
||||||
/// allocated memory.
|
/// allocated memory.
|
||||||
virtual void* allocate(size_t size) override {
|
virtual void* allocate(size_t size) override {
|
||||||
|
|
||||||
return malloc(size);
|
return std::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release previously allocated memory.
|
/// Release previously allocated memory.
|
||||||
virtual void release(void* pointer, size_t size) override {
|
virtual void release(void* pointer, size_t size) override {
|
||||||
free(pointer);
|
std::free(pointer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <reactphysics3d/configuration.h>
|
#include <reactphysics3d/configuration.h>
|
||||||
#include <reactphysics3d/memory/MemoryAllocator.h>
|
#include <reactphysics3d/memory/MemoryAllocator.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <mutex>
|
||||||
#include <reactphysics3d/containers/Map.h>
|
#include <reactphysics3d/containers/Map.h>
|
||||||
|
|
||||||
/// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
|
@ -88,6 +89,9 @@ class HeapAllocator : public MemoryAllocator {
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
|
// Mutex
|
||||||
|
std::mutex mMutex;
|
||||||
|
|
||||||
/// Base memory allocator
|
/// Base memory allocator
|
||||||
MemoryAllocator& mBaseAllocator;
|
MemoryAllocator& mBaseAllocator;
|
||||||
|
|
||||||
|
@ -117,6 +121,9 @@ class HeapAllocator : public MemoryAllocator {
|
||||||
// Merge two contiguous memory units that are not allocated.
|
// Merge two contiguous memory units that are not allocated.
|
||||||
void mergeUnits(MemoryUnitHeader* unit1, MemoryUnitHeader* unit2);
|
void mergeUnits(MemoryUnitHeader* unit1, MemoryUnitHeader* unit2);
|
||||||
|
|
||||||
|
/// Reserve more memory for the allocator
|
||||||
|
void reserve(size_t sizeToAllocate);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -128,7 +135,7 @@ class HeapAllocator : public MemoryAllocator {
|
||||||
virtual ~HeapAllocator() override;
|
virtual ~HeapAllocator() override;
|
||||||
|
|
||||||
/// Assignment operator
|
/// Assignment operator
|
||||||
HeapAllocator& operator=(HeapAllocator& allocator) = default;
|
HeapAllocator& operator=(HeapAllocator& allocator) = delete;
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -136,9 +143,6 @@ class HeapAllocator : public MemoryAllocator {
|
||||||
|
|
||||||
/// Release previously allocated memory.
|
/// Release previously allocated memory.
|
||||||
virtual void release(void* pointer, size_t size) override;
|
virtual void release(void* pointer, size_t size) override;
|
||||||
|
|
||||||
/// Reserve more memory for the allocator
|
|
||||||
void reserve(size_t sizeToAllocate);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include <reactphysics3d/configuration.h>
|
#include <reactphysics3d/configuration.h>
|
||||||
#include <reactphysics3d/memory/MemoryAllocator.h>
|
#include <reactphysics3d/memory/MemoryAllocator.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
/// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
@ -101,6 +102,9 @@ class PoolAllocator : public MemoryAllocator {
|
||||||
/// True if the mMapSizeToHeapIndex array has already been initialized
|
/// True if the mMapSizeToHeapIndex array has already been initialized
|
||||||
static bool isMapSizeToHeadIndexInitialized;
|
static bool isMapSizeToHeadIndexInitialized;
|
||||||
|
|
||||||
|
/// Mutex
|
||||||
|
std::mutex mMutex;
|
||||||
|
|
||||||
/// Base memory allocator
|
/// Base memory allocator
|
||||||
MemoryAllocator& mBaseAllocator;
|
MemoryAllocator& mBaseAllocator;
|
||||||
|
|
||||||
|
@ -135,7 +139,7 @@ class PoolAllocator : public MemoryAllocator {
|
||||||
virtual ~PoolAllocator() override;
|
virtual ~PoolAllocator() override;
|
||||||
|
|
||||||
/// Assignment operator
|
/// Assignment operator
|
||||||
PoolAllocator& operator=(PoolAllocator& allocator) = default;
|
PoolAllocator& operator=(PoolAllocator& allocator) = delete;
|
||||||
|
|
||||||
/// 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.
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include <reactphysics3d/memory/MemoryAllocator.h>
|
#include <reactphysics3d/memory/MemoryAllocator.h>
|
||||||
#include <reactphysics3d/configuration.h>
|
#include <reactphysics3d/configuration.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
/// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
@ -53,6 +54,9 @@ class SingleFrameAllocator : public MemoryAllocator {
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
|
/// Mutex
|
||||||
|
std::mutex mMutex;
|
||||||
|
|
||||||
/// Reference to the base memory allocator
|
/// Reference to the base memory allocator
|
||||||
MemoryAllocator& mBaseAllocator;
|
MemoryAllocator& mBaseAllocator;
|
||||||
|
|
||||||
|
@ -83,7 +87,7 @@ class SingleFrameAllocator : public MemoryAllocator {
|
||||||
virtual ~SingleFrameAllocator() override;
|
virtual ~SingleFrameAllocator() override;
|
||||||
|
|
||||||
/// Assignment operator
|
/// Assignment operator
|
||||||
SingleFrameAllocator& operator=(SingleFrameAllocator& allocator) = default;
|
SingleFrameAllocator& operator=(SingleFrameAllocator& allocator) = delete;
|
||||||
|
|
||||||
/// Allocate memory of a given size (in bytes)
|
/// Allocate memory of a given size (in bytes)
|
||||||
virtual void* allocate(size_t size) override;
|
virtual void* allocate(size_t size) override;
|
||||||
|
|
|
@ -107,6 +107,9 @@ void HeapAllocator::splitMemoryUnit(MemoryUnitHeader* unit, size_t size) {
|
||||||
// allocated memory.
|
// allocated memory.
|
||||||
void* HeapAllocator::allocate(size_t size) {
|
void* HeapAllocator::allocate(size_t size) {
|
||||||
|
|
||||||
|
// Lock the method with a mutex
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
// We cannot allocate zero bytes
|
// We cannot allocate zero bytes
|
||||||
|
@ -176,6 +179,9 @@ void* HeapAllocator::allocate(size_t size) {
|
||||||
// Release previously allocated memory.
|
// Release previously allocated memory.
|
||||||
void HeapAllocator::release(void* pointer, size_t size) {
|
void HeapAllocator::release(void* pointer, size_t size) {
|
||||||
|
|
||||||
|
// Lock the method with a mutex
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
// Cannot release a 0-byte allocated memory
|
// Cannot release a 0-byte allocated memory
|
||||||
|
|
|
@ -100,6 +100,9 @@ PoolAllocator::~PoolAllocator() {
|
||||||
// allocated memory.
|
// allocated memory.
|
||||||
void* PoolAllocator::allocate(size_t size) {
|
void* PoolAllocator::allocate(size_t size) {
|
||||||
|
|
||||||
|
// Lock the method with a mutex
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
// We cannot allocate zero bytes
|
// We cannot allocate zero bytes
|
||||||
|
@ -175,6 +178,9 @@ void* PoolAllocator::allocate(size_t size) {
|
||||||
// Release previously allocated memory.
|
// Release previously allocated memory.
|
||||||
void PoolAllocator::release(void* pointer, size_t size) {
|
void PoolAllocator::release(void* pointer, size_t size) {
|
||||||
|
|
||||||
|
// Lock the method with a mutex
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
// Cannot release a 0-byte allocated memory
|
// Cannot release a 0-byte allocated memory
|
||||||
|
|
|
@ -53,6 +53,9 @@ SingleFrameAllocator::~SingleFrameAllocator() {
|
||||||
// allocated memory.
|
// allocated memory.
|
||||||
void* SingleFrameAllocator::allocate(size_t size) {
|
void* SingleFrameAllocator::allocate(size_t size) {
|
||||||
|
|
||||||
|
// Lock the method with a mutex
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
// Check that there is enough remaining memory in the buffer
|
// Check that there is enough remaining memory in the buffer
|
||||||
if (mCurrentOffset + size > mTotalSizeBytes) {
|
if (mCurrentOffset + size > mTotalSizeBytes) {
|
||||||
|
|
||||||
|
@ -76,6 +79,9 @@ void* SingleFrameAllocator::allocate(size_t size) {
|
||||||
// Release previously allocated memory.
|
// Release previously allocated memory.
|
||||||
void SingleFrameAllocator::release(void* pointer, size_t size) {
|
void SingleFrameAllocator::release(void* pointer, size_t size) {
|
||||||
|
|
||||||
|
// Lock the method with a mutex
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
// If allocated memory is not within the single frame allocation range
|
// If allocated memory is not within the single frame allocation range
|
||||||
char* p = static_cast<char*>(pointer);
|
char* p = static_cast<char*>(pointer);
|
||||||
if (p < mMemoryBufferStart || p > mMemoryBufferStart + mTotalSizeBytes) {
|
if (p < mMemoryBufferStart || p > mMemoryBufferStart + mTotalSizeBytes) {
|
||||||
|
@ -88,6 +94,9 @@ void SingleFrameAllocator::release(void* pointer, size_t size) {
|
||||||
// Reset the marker of the current allocated memory
|
// Reset the marker of the current allocated memory
|
||||||
void SingleFrameAllocator::reset() {
|
void SingleFrameAllocator::reset() {
|
||||||
|
|
||||||
|
// Lock the method with a mutex
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
// If too much memory is allocated
|
// If too much memory is allocated
|
||||||
if (mCurrentOffset < mTotalSizeBytes / 2) {
|
if (mCurrentOffset < mTotalSizeBytes / 2) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user