Make memory allocators thread-safe

This commit is contained in:
Daniel Chappuis 2019-02-22 07:27:47 +01:00
parent 22109d02ff
commit 2ce0f8d76f
5 changed files with 36 additions and 1 deletions

View File

@ -29,6 +29,7 @@
// Libraries // Libraries
#include "memory/MemoryAllocator.h" #include "memory/MemoryAllocator.h"
#include <cstdlib> #include <cstdlib>
#include <mutex>
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -39,6 +40,11 @@ namespace reactphysics3d {
*/ */
class DefaultAllocator : public MemoryAllocator { class DefaultAllocator : public MemoryAllocator {
protected:
/// Mutex
std::mutex mMutex;
public: public:
/// Destructor /// Destructor
@ -50,11 +56,19 @@ class DefaultAllocator : public MemoryAllocator {
/// 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.
virtual void* allocate(size_t size) override { virtual void* allocate(size_t size) override {
// Lock the method with a mutex
std::lock_guard<std::mutex> lock(mMutex);
return malloc(size); return 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 {
// Lock the method with a mutex
std::lock_guard<std::mutex> lock(mMutex);
free(pointer); free(pointer);
} }
}; };

View File

@ -100,6 +100,9 @@ DefaultPoolAllocator::~DefaultPoolAllocator() {
// allocated memory. // allocated memory.
void* DefaultPoolAllocator::allocate(size_t size) { void* DefaultPoolAllocator::allocate(size_t size) {
// Lock the method with a mutex
std::lock_guard<std::mutex> lock(mMutex);
// We cannot allocate zero bytes // We cannot allocate zero bytes
if (size == 0) return nullptr; if (size == 0) return nullptr;
@ -173,6 +176,9 @@ void* DefaultPoolAllocator::allocate(size_t size) {
// Release previously allocated memory. // Release previously allocated memory.
void DefaultPoolAllocator::release(void* pointer, size_t size) { void DefaultPoolAllocator::release(void* pointer, size_t size) {
// Lock the method with a mutex
std::lock_guard<std::mutex> lock(mMutex);
// Cannot release a 0-byte allocated memory // Cannot release a 0-byte allocated memory
if (size == 0) return; if (size == 0) return;

View File

@ -29,6 +29,7 @@
// Libraries // Libraries
#include "configuration.h" #include "configuration.h"
#include "MemoryAllocator.h" #include "MemoryAllocator.h"
#include <mutex>
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -101,6 +102,9 @@ class DefaultPoolAllocator : 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;
/// Pointers to the first free memory unit for each heap /// Pointers to the first free memory unit for each heap
MemoryUnit* mFreeMemoryUnits[NB_HEAPS]; MemoryUnit* mFreeMemoryUnits[NB_HEAPS];

View File

@ -54,6 +54,9 @@ DefaultSingleFrameAllocator::~DefaultSingleFrameAllocator() {
// allocated memory. // allocated memory.
void* DefaultSingleFrameAllocator::allocate(size_t size) { void* DefaultSingleFrameAllocator::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) {
@ -77,6 +80,9 @@ void* DefaultSingleFrameAllocator::allocate(size_t size) {
// Release previously allocated memory. // Release previously allocated memory.
void DefaultSingleFrameAllocator::release(void* pointer, size_t size) { void DefaultSingleFrameAllocator::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) {

View File

@ -29,6 +29,7 @@
// Libraries // Libraries
#include "MemoryAllocator.h" #include "MemoryAllocator.h"
#include "configuration.h" #include "configuration.h"
#include <mutex>
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -52,6 +53,10 @@ class DefaultSingleFrameAllocator : public SingleFrameAllocator {
static const size_t INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES = 1048576; // 1Mb static const size_t INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES = 1048576; // 1Mb
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Mutex
std::mutex mMutex;
/// Cached memory allocator used on construction /// Cached memory allocator used on construction
MemoryAllocator* mBaseMemoryAllocator; MemoryAllocator* mBaseMemoryAllocator;