From ee50790398791c38e563eee04cf12780fab74baf Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 16 Jun 2014 15:12:50 +0100 Subject: Merge branch 'master' of github.com:mc-server/MCServer --- src/AllocationPool.h | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/AllocationPool.h (limited to 'src/AllocationPool.h') diff --git a/src/AllocationPool.h b/src/AllocationPool.h new file mode 100644 index 000000000..5d749a79e --- /dev/null +++ b/src/AllocationPool.h @@ -0,0 +1,109 @@ + +#pragma once + +#include + +template +class cAllocationPool +{ +public: + class cStarvationCallbacks + { + public: + virtual ~cStarvationCallbacks() {} + + /** Is called when the reserve buffer starts to be used **/ + virtual void OnStartUsingReserve() = 0; + + /** Is called once the reserve buffer has returned to normal size **/ + virtual void OnEndUsingReserve() = 0; + + /** Is called when the allocation pool is unable to allocate memory. Will be repeatedly + called if it does not free sufficient memory **/ + virtual void OnOutOfReserve() = 0; + }; + + virtual ~cAllocationPool() {} + + /** Allocates a pointer to T **/ + virtual T * Allocate() = 0; + + /** Frees the pointer passed in a_ptr, invalidating it **/ + virtual void Free(T * a_ptr) = 0; +}; + +/** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve +elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/ +template +class cListAllocationPool : public cAllocationPool +{ + public: + + cListAllocationPool(std::auto_ptr::cStarvationCallbacks> a_Callbacks) : + m_Callbacks(a_Callbacks) + { + for (size_t i = 0; i < NumElementsInReserve; i++) + { + void * space = malloc(sizeof(T)); + if (space == NULL) + { + m_Callbacks->OnStartUsingReserve(); + break; + } + m_FreeList.push_front(space); + } + } + + virtual ~cListAllocationPool() + { + while (!m_FreeList.empty()) + { + free (m_FreeList.front()); + m_FreeList.pop_front(); + } + } + + virtual T * Allocate() override + { + if (m_FreeList.size() <= NumElementsInReserve) + { + void * space = malloc(sizeof(T)); + if (space != NULL) + { + return new(space) T; + } + else if (m_FreeList.size() == NumElementsInReserve) + { + m_Callbacks->OnStartUsingReserve(); + } + else if (m_FreeList.empty()) + { + m_Callbacks->OnOutOfReserve(); + // Try again until the memory is avalable + return Allocate(); + } + } + // placement new, used to initalize the object + T * ret = new (m_FreeList.front()) T; + m_FreeList.pop_front(); + return ret; + } + virtual void Free(T * a_ptr) override + { + if (a_ptr == NULL) + { + return; + } + // placement destruct. + a_ptr->~T(); + m_FreeList.push_front(a_ptr); + if (m_FreeList.size() == NumElementsInReserve) + { + m_Callbacks->OnEndUsingReserve(); + } + } + + private: + std::list m_FreeList; + std::auto_ptr::cStarvationCallbacks> m_Callbacks; +}; -- cgit v1.2.3 From 993fd14ddfc881cf5be951df77da0338124d68cc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 17 Jul 2014 16:33:09 +0200 Subject: Fixed basic whitespace problems. Indenting by spaces and alignment by spaces, as well as trailing whitespace on non-empty lines. --- src/AllocationPool.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/AllocationPool.h') diff --git a/src/AllocationPool.h b/src/AllocationPool.h index 5d749a79e..3c9dbe8c9 100644 --- a/src/AllocationPool.h +++ b/src/AllocationPool.h @@ -61,7 +61,7 @@ class cListAllocationPool : public cAllocationPool free (m_FreeList.front()); m_FreeList.pop_front(); } - } + } virtual T * Allocate() override { @@ -90,7 +90,7 @@ class cListAllocationPool : public cAllocationPool } virtual void Free(T * a_ptr) override { - if (a_ptr == NULL) + if (a_ptr == NULL) { return; } @@ -107,3 +107,7 @@ class cListAllocationPool : public cAllocationPool std::list m_FreeList; std::auto_ptr::cStarvationCallbacks> m_Callbacks; }; + + + + -- cgit v1.2.3