From 88b91de197e50e09e27e56aa8f9c4493927dc39e Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 12 Jun 2020 11:53:59 -0700 Subject: [PATCH] Prepare to make MemoryDynamic --- src/mesh/MemoryPool.h | 88 ++++++++++++++++++++++++++----------------- src/mesh/MeshTypes.h | 2 +- src/mesh/Router.cpp | 4 +- 3 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/mesh/MemoryPool.h b/src/mesh/MemoryPool.h index 89c514c90..7f051af13 100644 --- a/src/mesh/MemoryPool.h +++ b/src/mesh/MemoryPool.h @@ -5,12 +5,58 @@ #include "PointerQueue.h" +template class Allocator +{ + + public: + virtual ~Allocator() {} + + /// Return a queable object which has been prefilled with zeros. Panic if no buffer is available + /// Note: this method is safe to call from regular OR ISR code + T *allocZeroed() + { + T *p = allocZeroed(0); + + assert(p); // FIXME panic instead + return p; + } + + /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you probably + /// don't want this version). + T *allocZeroed(TickType_t maxWait) + { + T *p = alloc(maxWait); + assert(p); + + if (p) + memset(p, 0, sizeof(T)); + return p; + } + + /// Return a queable object which is a copy of some other object + T *allocCopy(const T &src, TickType_t maxWait = portMAX_DELAY) + { + T *p = alloc(maxWait); + assert(p); + + if (p) + *p = src; + return p; + } + + /// Return a buffer for use by others + virtual void release(T *p) = 0; + + protected: + // Alloc some storage + virtual T *alloc(TickType_t maxWait) = 0; +}; + /** * A pool based allocator * - * Eventually this routine will even be safe for ISR use... */ -template class MemoryPool +template class MemoryPool : public Allocator { PointerQueue dead; @@ -30,39 +76,8 @@ template class MemoryPool ~MemoryPool() { delete[] buf; } - /// Return a queable object which has been prefilled with zeros. Panic if no buffer is available - /// Note: this method is safe to call from regular OR ISR code - T *allocZeroed() - { - T *p = allocZeroed(0); - - assert(p); // FIXME panic instead - return p; - } - - /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you probably - /// don't want this version). - T *allocZeroed(TickType_t maxWait) - { - T *p = dead.dequeuePtr(maxWait); - - if (p) - memset(p, 0, sizeof(T)); - return p; - } - - /// Return a queable object which is a copy of some other object - T *allocCopy(const T &src, TickType_t maxWait = portMAX_DELAY) - { - T *p = dead.dequeuePtr(maxWait); - - if (p) - *p = src; - return p; - } - /// Return a buffer for use by others - void release(T *p) + virtual void release(T *p) { assert(dead.enqueue(p, 0)); assert(p >= buf && @@ -78,4 +93,9 @@ template class MemoryPool (size_t)(p - buf) < maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool } + + protected: + /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you + /// probably don't want this version). + virtual T *alloc(TickType_t maxWait) { return dead.dequeuePtr(maxWait); } }; diff --git a/src/mesh/MeshTypes.h b/src/mesh/MeshTypes.h index 32ec2b08d..7c58b2e3e 100644 --- a/src/mesh/MeshTypes.h +++ b/src/mesh/MeshTypes.h @@ -29,4 +29,4 @@ typedef uint32_t PacketId; // A packet sequence number typedef int ErrorCode; /// Alloc and free packets to our global, ISR safe pool -extern MemoryPool packetPool; \ No newline at end of file +extern Allocator &packetPool; \ No newline at end of file diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 2f8dd5e28..f9b196d60 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -23,7 +23,9 @@ (MAX_RX_TOPHONE + MAX_RX_FROMRADIO + MAX_TX_QUEUE + \ 2) // max number of packets which can be in flight (either queued from reception or queued for sending) -MemoryPool packetPool(MAX_PACKETS); + +static MemoryPool staticPool(MAX_PACKETS); +Allocator &packetPool = staticPool; /** * Constructor