mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Hoisted pool functionality
This commit is contained in:
parent
455377a764
commit
e0e7d20a9b
101
ipool.h
101
ipool.h
@ -30,33 +30,88 @@ SOFTWARE.
|
||||
#define __ETL_IPOOL__
|
||||
#define __ETL_IN_IPOOL_H__
|
||||
|
||||
//*****************************************************************************
|
||||
///\defgroup pool pool
|
||||
/// A fixed capacity pool.
|
||||
///\ingroup containers
|
||||
//*****************************************************************************
|
||||
#include "pool_base.h"
|
||||
#include "nullptr.h"
|
||||
|
||||
#ifndef ETL_THROW_EXCEPTIONS
|
||||
#include "error_handler.h"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//*************************************************************************
|
||||
/// A templated pool implementation that uses a fixed size pool.
|
||||
/// SIZE_ elements will be always be constructed.
|
||||
///\ingroup pool
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
class ipool : public pool_base
|
||||
{
|
||||
private:
|
||||
|
||||
struct element
|
||||
{
|
||||
T* p_item;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an object from the pool.
|
||||
/// If ETL_THROW_EXCEPTIONS is defined and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a nullptr is returned.
|
||||
/// \note The state of the object returned is undefined.
|
||||
//*************************************************************************
|
||||
T* allocate()
|
||||
{
|
||||
if (next_free)
|
||||
if (next_free != MAX_SIZE)
|
||||
{
|
||||
T* result = &p_buffer[next_free];
|
||||
in_use_flags.set(next_free);
|
||||
next_free = in_use_flags.find_first(false);
|
||||
++items_allocated;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ETL_THROW_EXCEPTIONS
|
||||
throw pool_no_allocation();
|
||||
#else
|
||||
error_handler::error(pool_no_allocation());
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Free an object in the pool.
|
||||
/// If ETL_THROW_EXCEPTIONS is defined and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// \param p_object A pointer to the object to be released.
|
||||
//*************************************************************************
|
||||
void release(const T& object)
|
||||
{
|
||||
release(&object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Free an object in the pool.
|
||||
/// If ETL_THROW_EXCEPTIONS is defined and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// \param p_object A pointer to the object to be released.
|
||||
//*************************************************************************
|
||||
void release(const T* const p_object)
|
||||
{
|
||||
// Does this object belong to this pool?
|
||||
typename std::iterator_traits<T*>::difference_type distance = p_object - p_buffer;
|
||||
|
||||
// Not within the range of the buffer?
|
||||
if ((distance < 0) || (distance >= static_cast<typename std::iterator_traits<T*>::difference_type>(MAX_SIZE)))
|
||||
{
|
||||
#ifdef ETL_THROW_EXCEPTIONS
|
||||
throw pool_object_not_in_pool();
|
||||
#else
|
||||
error_handler::error(pool_object_not_in_pool());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mark the object as available.
|
||||
next_free = static_cast<size_t>(distance);
|
||||
in_use_flags.reset(next_free);
|
||||
--items_allocated;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -64,19 +119,15 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
ipool(T* p_buffer, size_t size)
|
||||
: next_free(0),
|
||||
p_buffer(p_buffer),
|
||||
SIZE(size)
|
||||
|
||||
ipool(T* p_buffer, ibitset& in_use_flags, size_t size)
|
||||
: pool_base(size),
|
||||
p_buffer(nullptr),
|
||||
in_use_flags(in_use_flags)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
size_t next_free;
|
||||
T* p_buffer;
|
||||
const size_t SIZE;
|
||||
T* p_buffer;
|
||||
ibitset& in_use_flags;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
131
pool.h
131
pool.h
@ -30,7 +30,7 @@ SOFTWARE.
|
||||
#define __ETL_POOL__
|
||||
|
||||
#include "bitset.h"
|
||||
#include "nullptr.h"
|
||||
#include "ipool.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
@ -42,54 +42,13 @@ SOFTWARE.
|
||||
|
||||
namespace etl
|
||||
{
|
||||
#ifdef ETL_THROW_EXCEPTIONS
|
||||
//***************************************************************************
|
||||
/// The base class for pool exceptions.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_exception(const char* what)
|
||||
: exception(what)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the pool has no more free items.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_no_allocation : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_no_allocation()
|
||||
: pool_exception("pool: no allocation")
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when an object is released which does not belong to the pool.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_object_not_in_pool : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_object_not_in_pool()
|
||||
: pool_exception("pool: not in pool")
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// A templated pool implementation that uses a fixed size pool.
|
||||
/// SIZE_ elements will be always be constructed.
|
||||
///\ingroup pool
|
||||
//*************************************************************************
|
||||
template <typename T, const size_t SIZE_>
|
||||
class pool
|
||||
class pool : public ipool<T>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -99,96 +58,12 @@ namespace etl
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
pool()
|
||||
: next_free(0),
|
||||
count(0)
|
||||
: ipool(buffer, in_use, SIZE)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an object from the pool.
|
||||
/// If ETL_THROW_EXCEPTIONS is defined and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a nullptr is returned.
|
||||
/// \note The state of the object returned is undefined.
|
||||
//*************************************************************************
|
||||
T* allocate()
|
||||
{
|
||||
if (next_free != SIZE)
|
||||
{
|
||||
T* result = &buffer[next_free];
|
||||
in_use.set(next_free);
|
||||
next_free = in_use.find_first(false);
|
||||
++count;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ETL_THROW_EXCEPTIONS
|
||||
throw pool_no_allocation();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Free an object in the pool.
|
||||
/// If ETL_THROW_EXCEPTIONS is defined and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// \param object A reference to the object to be released.
|
||||
//*************************************************************************
|
||||
void release(const T& object)
|
||||
{
|
||||
release(&object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Free an object in the pool.
|
||||
/// If ETL_THROW_EXCEPTIONS is defined and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// \param p_object A pointer to the object to be released.
|
||||
//*************************************************************************
|
||||
void release(const T* const p_object)
|
||||
{
|
||||
// Does this object belong to this pool?
|
||||
typename std::iterator_traits<T*>::difference_type distance = p_object - buffer;
|
||||
|
||||
// Not within the range of the buffer?
|
||||
if ((distance < 0) || (distance >= SIZE))
|
||||
{
|
||||
#ifdef ETL_THROW_EXCEPTIONS
|
||||
throw pool_object_not_in_pool();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mark the object as available.
|
||||
next_free = static_cast<size_t>(distance);
|
||||
in_use.reset(next_free);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of free items in the pool.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return SIZE - in_use.count();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no free items in the pool.
|
||||
/// \return <b>true</b> if there are none free (or 'empty')
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return count == SIZE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
size_t next_free; ///< The position of the next free item in the pool.
|
||||
size_t count; ///< The number of objects allocated.
|
||||
T buffer[SIZE]; ///< The pool of objects.
|
||||
bitset<SIZE> in_use; ///< The set of flags that indicate which items are free in the pool.
|
||||
};
|
||||
|
||||
128
pool_base.h
Normal file
128
pool_base.h
Normal file
@ -0,0 +1,128 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __ETL_IN_IPOOL_H__
|
||||
#error This header is a private element of etl::pool & etl::ipool
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_POOL_BASE__
|
||||
#define __ETL_POOL_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "exception.h"
|
||||
|
||||
#ifndef ETL_THROW_EXCEPTIONS
|
||||
#include "error_handler.h"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for pool exceptions.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_exception(const char* what)
|
||||
: exception(what)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the pool has no more free items.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_no_allocation : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_no_allocation()
|
||||
: pool_exception("pool: no allocation")
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when an object is released which does not belong to the pool.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_object_not_in_pool : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_object_not_in_pool()
|
||||
: pool_exception("pool: not in pool")
|
||||
{}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The base class for all templated pool types.
|
||||
///\ingroup pool
|
||||
//*************************************************************************
|
||||
class pool_base
|
||||
{
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of free items in the pool.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return MAX_SIZE - items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no free items in the pool.
|
||||
/// \return <b>true</b> if there are none free (or 'empty')
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return items_allocated == MAX_SIZE;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
pool_base(size_t max_size)
|
||||
: next_free(0),
|
||||
items_allocated(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
size_t next_free; ///< The position of the next free item in the pool.
|
||||
size_t items_allocated; ///< The number of items allocated.
|
||||
const size_t MAX_SIZE; ///< The maximum number of objects that can be allocated.
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -140,11 +140,13 @@
|
||||
<ClInclude Include="..\..\function.h" />
|
||||
<ClInclude Include="..\..\functional.h" />
|
||||
<ClInclude Include="..\..\hash.h" />
|
||||
<ClInclude Include="..\..\ibitset.h" />
|
||||
<ClInclude Include="..\..\ideque.h" />
|
||||
<ClInclude Include="..\..\iforward_list.h" />
|
||||
<ClInclude Include="..\..\ilist.h" />
|
||||
<ClInclude Include="..\..\instance_count.h" />
|
||||
<ClInclude Include="..\..\integral_limits.h" />
|
||||
<ClInclude Include="..\..\ipool.h" />
|
||||
<ClInclude Include="..\..\iqueue.h" />
|
||||
<ClInclude Include="..\..\istack.h" />
|
||||
<ClInclude Include="..\..\container.h" />
|
||||
@ -159,6 +161,7 @@
|
||||
<ClInclude Include="..\..\parameter_type.h" />
|
||||
<ClInclude Include="..\..\platform.h" />
|
||||
<ClInclude Include="..\..\pool.h" />
|
||||
<ClInclude Include="..\..\pool_base.h" />
|
||||
<ClInclude Include="..\..\power.h" />
|
||||
<ClInclude Include="..\..\queue.h" />
|
||||
<ClInclude Include="..\..\queue_base.h" />
|
||||
|
||||
@ -300,6 +300,15 @@
|
||||
<ClInclude Include="..\..\hash.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ipool.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\pool_base.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ibitset.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\unittest-cpp\UnitTest++\AssertException.cpp">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user