Simplified global and context code / prefer references to pointers
This commit is contained in:
@@ -19,8 +19,62 @@
|
||||
*/
|
||||
|
||||
class FrameLib_Context
|
||||
{
|
||||
using Global = FrameLib_Global;
|
||||
{
|
||||
/**
|
||||
|
||||
\class ManagedPointer
|
||||
|
||||
\brief a managed pointer for a context-related result.
|
||||
|
||||
This is a non-copyable class that uses RAII to update the reference counted pointer in FrameLib_Global
|
||||
|
||||
*/
|
||||
|
||||
template <class T, FrameLib_Global::PointerSet<T> FrameLib_Global::*PointerSet>
|
||||
class ManagedPointer
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Constructor / Destructor
|
||||
|
||||
ManagedPointer(const FrameLib_Context &context) : mGlobal(context.mGlobal), mReference(context.mReference)
|
||||
{
|
||||
mPointer = (mGlobal->*PointerSet).get(mReference);
|
||||
}
|
||||
|
||||
~ManagedPointer()
|
||||
{
|
||||
(mGlobal->*PointerSet).release(mReference);
|
||||
mPointer = nullptr;
|
||||
mGlobal = nullptr;
|
||||
mReference = nullptr;
|
||||
}
|
||||
|
||||
// Non-copyable
|
||||
|
||||
ManagedPointer(const ManagedPointer&) = delete;
|
||||
ManagedPointer& operator=(const ManagedPointer&) = delete;
|
||||
|
||||
// Pointer dereferencing
|
||||
|
||||
T *operator->() { return mPointer; }
|
||||
T& operator*() { return *mPointer; }
|
||||
|
||||
private:
|
||||
|
||||
// Member Variables
|
||||
|
||||
FrameLib_Global *mGlobal;
|
||||
void *mReference;
|
||||
T *mPointer;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
// Constructor - the reference should be a suitable reference address in the host environment
|
||||
|
||||
FrameLib_Context(FrameLib_Global *global, void *reference) : mGlobal(global), mReference(reference) {}
|
||||
|
||||
// Comparisions
|
||||
|
||||
@@ -34,74 +88,10 @@ class FrameLib_Context
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
\class ManagedPointer
|
||||
|
||||
\brief a managed pointer for a context-related result.
|
||||
|
||||
This is a non-copyable class that uses RAII to update the reference counted pointer in FrameLib_Global
|
||||
|
||||
*/
|
||||
|
||||
template <class T, T *(Global::*getMethod)(void *), void(Global::*releaseMethod)(void *)>
|
||||
class ManagedPointer
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Constructor / Destructor
|
||||
|
||||
ManagedPointer(const FrameLib_Context &context) : mGlobal(context.mGlobal), mReference(context.mReference)
|
||||
{
|
||||
mPointer = (mGlobal->*getMethod)(mReference);
|
||||
}
|
||||
|
||||
~ManagedPointer()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
// Non-copyable
|
||||
|
||||
ManagedPointer(const ManagedPointer&) = delete;
|
||||
ManagedPointer& operator=(const ManagedPointer&) = delete;
|
||||
|
||||
// Release
|
||||
|
||||
void release()
|
||||
{
|
||||
if (mGlobal)
|
||||
(mGlobal->*releaseMethod)(mReference);
|
||||
mPointer = nullptr;
|
||||
mGlobal = nullptr;
|
||||
mReference = nullptr;
|
||||
}
|
||||
|
||||
// Pointer / Bool Conversion
|
||||
|
||||
T *operator->() { return mPointer; }
|
||||
operator bool() const { return mPointer != nullptr; }
|
||||
|
||||
private:
|
||||
|
||||
// Member Variables
|
||||
|
||||
T *mPointer;
|
||||
FrameLib_Global *mGlobal;
|
||||
void *mReference;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
// Constructor - the reference should be a suitable reference address in the host environment
|
||||
|
||||
FrameLib_Context(FrameLib_Global *global, void *reference) : mGlobal(global), mReference(reference) {}
|
||||
|
||||
// Construct one of these objects to retain a relevant object
|
||||
|
||||
using Allocator = ManagedPointer<FrameLib_LocalAllocator, &Global::getAllocator, &Global::releaseAllocator>;
|
||||
using ProcessingQueue = ManagedPointer<FrameLib_ProcessingQueue, &Global::getProcessingQueue, &Global::releaseProcessingQueue>;
|
||||
using Allocator = ManagedPointer<FrameLib_LocalAllocator, &FrameLib_Global::mLocalAllocators>;
|
||||
using ProcessingQueue = ManagedPointer<FrameLib_ProcessingQueue, &FrameLib_Global::mProcessingQueues>;
|
||||
|
||||
// Get the global as a FrameLib_ErrorReporter from the context
|
||||
|
||||
|
||||
@@ -1,50 +1,6 @@
|
||||
|
||||
#include "FrameLib_Global.h"
|
||||
|
||||
// The PointerSet Template
|
||||
|
||||
// Add an object given a pointer (transferring ownership) and a reference address
|
||||
|
||||
template <class T>
|
||||
void FrameLib_Global::PointerSet<T>::add(T *object, void *reference)
|
||||
{
|
||||
mPointers.push_back(CountablePointer(object, reference));
|
||||
}
|
||||
|
||||
// Find a pre-exising object by reference address
|
||||
|
||||
template <class T>
|
||||
T *FrameLib_Global::PointerSet<T>::find(void *reference)
|
||||
{
|
||||
for (auto it = mPointers.begin(); it != mPointers.end(); it++)
|
||||
{
|
||||
if (it->mReference == reference)
|
||||
{
|
||||
it->mCount++;
|
||||
return it->mObject.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Release a pre-existing object by reference address
|
||||
|
||||
template <class T>
|
||||
void FrameLib_Global::template PointerSet<T>::release(void *reference)
|
||||
{
|
||||
for (auto it = mPointers.begin(); it != mPointers.end(); it++)
|
||||
{
|
||||
if (it->mReference == reference)
|
||||
{
|
||||
if (--it->mCount < 1)
|
||||
mPointers.erase(it);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Main Global Class
|
||||
|
||||
// Retrieve and release the global object
|
||||
@@ -63,46 +19,6 @@ void FrameLib_Global::release(FrameLib_Global **global)
|
||||
*global = (*global)->decrement();
|
||||
}
|
||||
|
||||
// Methods to retrieve common objects
|
||||
|
||||
FrameLib_LocalAllocator *FrameLib_Global::getAllocator(void *reference)
|
||||
{
|
||||
FrameLib_LocalAllocator *allocator = mLocalAllocators.find(reference);
|
||||
|
||||
if (!allocator)
|
||||
{
|
||||
allocator = new FrameLib_LocalAllocator(&mAllocator);
|
||||
mLocalAllocators.add(allocator, reference);
|
||||
}
|
||||
|
||||
return allocator;
|
||||
}
|
||||
|
||||
FrameLib_ProcessingQueue *FrameLib_Global::getProcessingQueue(void *reference)
|
||||
{
|
||||
FrameLib_ProcessingQueue *queue = mProcessingQueues.find(reference);
|
||||
|
||||
if (!queue)
|
||||
{
|
||||
queue = new FrameLib_ProcessingQueue(*this);
|
||||
mProcessingQueues.add(queue, reference);
|
||||
}
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
// Methods to release common objects
|
||||
|
||||
void FrameLib_Global::releaseAllocator(void *reference)
|
||||
{
|
||||
mLocalAllocators.release(reference);
|
||||
}
|
||||
|
||||
void FrameLib_Global::releaseProcessingQueue(void *reference)
|
||||
{
|
||||
mProcessingQueues.release(reference);
|
||||
}
|
||||
|
||||
// Reference Counting / Auto-deletion
|
||||
|
||||
void FrameLib_Global::increment()
|
||||
|
||||
@@ -32,7 +32,8 @@ class FrameLib_Global : public FrameLib_ErrorReporter
|
||||
|
||||
private:
|
||||
|
||||
template <class T> class PointerSet
|
||||
template <class T>
|
||||
class PointerSet
|
||||
{
|
||||
// A simple countable pointer with a reference address
|
||||
|
||||
@@ -47,16 +48,47 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
// Add, find or release an object by reference address
|
||||
PointerSet(FrameLib_Global& global) : mGlobal(global) {}
|
||||
|
||||
void add(T *object, void *reference);
|
||||
T *find(void *reference);
|
||||
void release(void *reference);
|
||||
// Get an object given a reference pointer
|
||||
|
||||
T *get(void *reference)
|
||||
{
|
||||
for (auto it = mPointers.begin(); it != mPointers.end(); it++)
|
||||
{
|
||||
if (it->mReference == reference)
|
||||
{
|
||||
it->mCount++;
|
||||
return it->mObject.get();
|
||||
}
|
||||
}
|
||||
|
||||
T *object = new T(mGlobal);
|
||||
mPointers.push_back(CountablePointer(object, reference));
|
||||
return object;
|
||||
}
|
||||
|
||||
// Release a pre-existing object by reference address
|
||||
|
||||
void release(void *reference)
|
||||
{
|
||||
for (auto it = mPointers.begin(); it != mPointers.end(); it++)
|
||||
{
|
||||
if (it->mReference == reference)
|
||||
{
|
||||
if (--it->mCount < 1)
|
||||
mPointers.erase(it);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Internal Pointers
|
||||
|
||||
FrameLib_Global& mGlobal;
|
||||
std::vector<CountablePointer> mPointers;
|
||||
};
|
||||
|
||||
@@ -90,7 +122,8 @@ private:
|
||||
|
||||
// Constructor / Destructor
|
||||
|
||||
FrameLib_Global(FrameLib_ErrorReporter::HostNotifier *notifier) : FrameLib_ErrorReporter(notifier), mAllocator(*this), mCount(0) {}
|
||||
FrameLib_Global(FrameLib_ErrorReporter::HostNotifier *notifier)
|
||||
: FrameLib_ErrorReporter(notifier), mAllocator(*this), mLocalAllocators(*this), mProcessingQueues(*this), mCount(0) {}
|
||||
~FrameLib_Global() {};
|
||||
|
||||
// Non-copyable
|
||||
@@ -98,21 +131,15 @@ private:
|
||||
FrameLib_Global(const FrameLib_Global&) = delete;
|
||||
FrameLib_Global& operator=(const FrameLib_Global&) = delete;
|
||||
|
||||
// Methods to retrieve common objects
|
||||
|
||||
FrameLib_LocalAllocator *getAllocator(void *reference);
|
||||
FrameLib_ProcessingQueue *getProcessingQueue(void *reference);
|
||||
|
||||
// Methods to release common objects
|
||||
|
||||
void releaseAllocator(void *reference);
|
||||
void releaseProcessingQueue(void *reference);
|
||||
|
||||
// Reference Counting / Auto-deletion
|
||||
|
||||
void increment();
|
||||
FrameLib_Global *decrement();
|
||||
|
||||
// Conversion to allocator for initisation of local allocators
|
||||
|
||||
operator FrameLib_GlobalAllocator& () { return mAllocator; }
|
||||
|
||||
// Member Variables
|
||||
|
||||
// Global Memory Allocator
|
||||
|
||||
@@ -29,7 +29,7 @@ inline size_t blockSize(void* ptr)
|
||||
|
||||
// The Core Allocator (has no threadsafety)
|
||||
|
||||
FrameLib_GlobalAllocator::CoreAllocator::CoreAllocator(FrameLib_ErrorReporter& errorReporter) : mPools(nullptr), mOSAllocated(0), mAllocated(0), mLastDisposedPoolSize(0), mScheduledNewPool(nullptr), mScheduledDisposePool(nullptr), mAllocThread(this), mFreeThread(this), mErrorReporter(errorReporter)
|
||||
FrameLib_GlobalAllocator::CoreAllocator::CoreAllocator(FrameLib_ErrorReporter& errorReporter) : mPools(nullptr), mOSAllocated(0), mAllocated(0), mLastDisposedPoolSize(0), mScheduledNewPool(nullptr), mScheduledDisposePool(nullptr), mAllocThread(*this), mFreeThread(*this), mErrorReporter(errorReporter)
|
||||
{
|
||||
mTLSF = tlsf_create(malloc(tlsf_size()));
|
||||
insertPool(createPool(initSize));
|
||||
@@ -273,7 +273,7 @@ size_t FrameLib_GlobalAllocator::alignSize(size_t x)
|
||||
|
||||
// Local Storage
|
||||
|
||||
FrameLib_LocalAllocator::Storage::Storage(const char *name, FrameLib_LocalAllocator *allocator)
|
||||
FrameLib_LocalAllocator::Storage::Storage(const char *name, FrameLib_LocalAllocator& allocator)
|
||||
: mName(name), mType(kFrameNormal), mData(nullptr), mSize(0), mMaxSize(0), mCount(1), mAllocator(allocator)
|
||||
{}
|
||||
|
||||
@@ -282,7 +282,7 @@ FrameLib_LocalAllocator::Storage::~Storage()
|
||||
if (mType == kFrameTagged)
|
||||
getTagged()->~Serial();
|
||||
|
||||
mAllocator->dealloc(mData);
|
||||
mAllocator.dealloc(mData);
|
||||
}
|
||||
|
||||
void FrameLib_LocalAllocator::Storage::resize(bool tagged, size_t size)
|
||||
@@ -306,7 +306,7 @@ void FrameLib_LocalAllocator::Storage::resize(bool tagged, size_t size)
|
||||
}
|
||||
else
|
||||
{
|
||||
void *newData = mAllocator->alloc(maxSize);
|
||||
void *newData = mAllocator.alloc(maxSize);
|
||||
|
||||
if (newData)
|
||||
{
|
||||
@@ -314,7 +314,7 @@ void FrameLib_LocalAllocator::Storage::resize(bool tagged, size_t size)
|
||||
|
||||
if (mType == kFrameTagged)
|
||||
getTagged()->~Serial();
|
||||
mAllocator->dealloc(mData);
|
||||
mAllocator.dealloc(mData);
|
||||
|
||||
// Allocate
|
||||
|
||||
@@ -337,7 +337,7 @@ void FrameLib_LocalAllocator::Storage::resize(bool tagged, size_t size)
|
||||
|
||||
// Constructor / Destructor
|
||||
|
||||
FrameLib_LocalAllocator::FrameLib_LocalAllocator(FrameLib_GlobalAllocator *allocator) : mAllocator(allocator)
|
||||
FrameLib_LocalAllocator::FrameLib_LocalAllocator(FrameLib_GlobalAllocator& allocator) : mAllocator(allocator)
|
||||
{
|
||||
// Setup the free lists as a circularly linked list
|
||||
|
||||
@@ -376,7 +376,7 @@ void *FrameLib_LocalAllocator::alloc(size_t size)
|
||||
|
||||
// If this fails call the global allocator
|
||||
|
||||
return mAllocator->alloc(size);
|
||||
return mAllocator.alloc(size);
|
||||
}
|
||||
|
||||
void FrameLib_LocalAllocator::dealloc(void *ptr)
|
||||
@@ -386,7 +386,7 @@ void FrameLib_LocalAllocator::dealloc(void *ptr)
|
||||
// If the free lists are full send the tail back to the global allocator
|
||||
|
||||
if (mTail->mMemory)
|
||||
mAllocator->dealloc(mTail->mMemory);
|
||||
mAllocator.dealloc(mTail->mMemory);
|
||||
|
||||
// Put the memory into the (now vacant) tail position
|
||||
|
||||
@@ -430,7 +430,7 @@ FrameLib_LocalAllocator::Storage *FrameLib_LocalAllocator::registerStorage(const
|
||||
return *it;
|
||||
}
|
||||
|
||||
mStorage.push_back(new Storage(name, this));
|
||||
mStorage.push_back(new Storage(name, *this));
|
||||
return mStorage.back();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,13 +78,13 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
NewThread(CoreAllocator *allocator) : FrameLib_DelegateThread(FrameLib_Thread::kHighPriority), mAllocator(allocator) {}
|
||||
NewThread(CoreAllocator& allocator) : FrameLib_DelegateThread(FrameLib_Thread::kHighPriority), mAllocator(allocator) {}
|
||||
|
||||
private:
|
||||
|
||||
void doTask() override { mAllocator->addScheduledPool(); };
|
||||
void doTask() override { mAllocator.addScheduledPool(); };
|
||||
|
||||
CoreAllocator *mAllocator;
|
||||
CoreAllocator& mAllocator;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -100,13 +100,13 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
FreeThread(CoreAllocator *allocator) : FrameLib_TriggerableThread(FrameLib_Thread::kLowPriority), mAllocator(allocator) {}
|
||||
FreeThread(CoreAllocator& allocator) : FrameLib_TriggerableThread(FrameLib_Thread::kLowPriority), mAllocator(allocator) {}
|
||||
|
||||
private:
|
||||
|
||||
void doTask() override { mAllocator->destroyScheduledPool(); };
|
||||
void doTask() override { mAllocator.destroyScheduledPool(); };
|
||||
|
||||
CoreAllocator *mAllocator;
|
||||
CoreAllocator& mAllocator;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -174,15 +174,15 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
Pruner(FrameLib_GlobalAllocator *allocator) : mAllocator(allocator)
|
||||
Pruner(FrameLib_GlobalAllocator& allocator) : mAllocator(allocator)
|
||||
{
|
||||
mAllocator->mLock.acquire();
|
||||
mAllocator.mLock.acquire();
|
||||
}
|
||||
|
||||
~Pruner()
|
||||
{
|
||||
mAllocator->mAllocator.prune();
|
||||
mAllocator->mLock.release();
|
||||
mAllocator.mAllocator.prune();
|
||||
mAllocator.mLock.release();
|
||||
}
|
||||
|
||||
// Non-copyable
|
||||
@@ -190,17 +190,15 @@ public:
|
||||
Pruner(const Pruner&) = delete;
|
||||
Pruner& operator=(const Pruner&) = delete;
|
||||
|
||||
void dealloc(void *ptr) { mAllocator->mAllocator.dealloc(ptr); }
|
||||
void dealloc(void *ptr) { mAllocator.mAllocator.dealloc(ptr); }
|
||||
|
||||
private:
|
||||
|
||||
// Allocator
|
||||
|
||||
FrameLib_GlobalAllocator *mAllocator;
|
||||
FrameLib_GlobalAllocator& mAllocator;
|
||||
};
|
||||
|
||||
// ************************************************************************************** //
|
||||
|
||||
// Constructor / Destructor
|
||||
|
||||
FrameLib_GlobalAllocator(FrameLib_ErrorReporter& errorReporter) : mAllocator(errorReporter) {}
|
||||
@@ -343,7 +341,7 @@ public:
|
||||
|
||||
// Constructor / Destructor
|
||||
|
||||
Storage(const char *name, FrameLib_LocalAllocator *allocator);
|
||||
Storage(const char *name, FrameLib_LocalAllocator& allocator);
|
||||
~Storage();
|
||||
|
||||
// Non-copyable
|
||||
@@ -368,12 +366,12 @@ public:
|
||||
unsigned long mCount;
|
||||
|
||||
FrameLib_SpinLock mLock;
|
||||
FrameLib_LocalAllocator *mAllocator;
|
||||
FrameLib_LocalAllocator& mAllocator;
|
||||
};
|
||||
|
||||
// Constructor / Destructor
|
||||
|
||||
FrameLib_LocalAllocator(FrameLib_GlobalAllocator *allocator);
|
||||
FrameLib_LocalAllocator(FrameLib_GlobalAllocator& allocator);
|
||||
~FrameLib_LocalAllocator();
|
||||
|
||||
// Non-copyable
|
||||
@@ -413,7 +411,7 @@ private:
|
||||
|
||||
// Member Variables
|
||||
|
||||
FrameLib_GlobalAllocator *mAllocator;
|
||||
FrameLib_GlobalAllocator& mAllocator;
|
||||
|
||||
FreeBlock mFreeLists[numLocalFreeBlocks];
|
||||
FreeBlock *mTail;
|
||||
|
||||
Reference in New Issue
Block a user