µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os::rtos::memory_pool Class Reference

Synchronised memory pool, using the default RTOS allocator. More...

#include <cmsis-plus/rtos/os.h>

+ Inheritance diagram for os::rtos::memory_pool:

Classes

class  arena
 Storage for a memory pool. More...
 
class  attributes
 Memory pool attributes. More...
 

Public Types

using allocator_type = memory::allocator< thread::stack::allocation_element_t >
 Default RTOS allocator.
 
using size_t = uint16_t
 Type of memory pool size storage.
 

Public Member Functions

template<typename T >
constexpr std::size_t compute_allocated_size_bytes (std::size_t blocks, std::size_t block_size_bytes)
 Calculator for pool storage requirements.
 
Constructors & Destructor
 memory_pool (std::size_t blocks, std::size_t block_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
 Construct a memory pool object instance.
 
 memory_pool (const char *name, std::size_t blocks, std::size_t block_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
 Construct a named memory pool object instance.
 
virtual ~memory_pool ()
 Destruct the memory pool object instance.
 
Operators
bool operator== (const memory_pool &rhs) const
 Compare memory pools.
 
Public Member Functions
void * alloc (void)
 Allocate a memory block.
 
void * try_alloc (void)
 Try to allocate a memory block.
 
void * timed_alloc (clock::duration_t timeout)
 Allocate a memory block with timeout.
 
result_t free (void *block)
 Free the memory block.
 
std::size_t capacity (void) const
 Get memory pool capacity.
 
std::size_t count (void) const
 Get blocks count.
 
std::size_t block_size (void) const
 Get block size.
 
bool empty (void) const
 Check if the memory pool is empty.
 
bool full (void) const
 Check if the memory pool is full.
 
result_t reset (void)
 Reset the memory pool.
 
void * pool (void)
 Get the pool storage address.
 
Public Member Functions
const char * name (void) const
 Get object name.
 

Static Public Member Functions

Operators
static void * operator new (std::size_t bytes)
 Allocate space for a new object instance using the RTOS system allocator.
 
static void * operator new (std::size_t bytes, void *ptr)
 Emplace a new object instance.
 
static void * operator new[] (std::size_t bytes)
 Allocate space for an array of new object instances using the RTOS system allocator.
 
static void * operator new[] (std::size_t bytes, void *ptr)
 Emplace an array of new object instances.
 
static void operator delete (void *ptr, std::size_t bytes)
 Deallocate the dynamically allocated object instance. using the RTOS system allocator.
 
static void operator delete[] (void *ptr, std::size_t bytes)
 Deallocate the dynamically allocated array of object. instances using the RTOS system allocator.
 

Static Public Attributes

static const attributes initializer
 Default memory pool initialiser.
 
static constexpr memory_pool::size_t max_size = static_cast<memory_pool::size_t> (0 - 1)
 Maximum pool size.
 

Detailed Description

Manage a pool of same size blocks. Fast and deterministic allocation and deallocation behaviour, suitable for use even in ISRs.

Example
// Define the type of one pool block.
typedef struct {
uint32_t length;
uint32_t width;
uint32_t height;
uint32_t weight;
} properties_t;
// Define the pool size.
constexpr uint32_t pool_size = 10;
// Construct the pool object instance.
memory_pool mp { pool_size, sizeof(properties_t) };
void
func(void)
{
// Do something
void* buf;
// Get one block from pool.
buf = mp.alloc();
// ... use the buffer
// Free the buffer.
mp.free(buf);
// Do something else.
}
Synchronised memory pool, using the default RTOS allocator.
Definition os-mempool.h:67
void * alloc(void)
Allocate a memory block.
Note
There is no equivalent of calloc(); to initialise to zero a memory block, use:
block = mp.alloc();
memset (block, 0, mp.block_size ());
POSIX compatibility
No POSIX similar functionality identified. Current functionality inspired by ARM CMSIS, with extensions.

Definition at line 66 of file os-mempool.h.

Member Typedef Documentation

◆ allocator_type

Constructor & Destructor Documentation

◆ memory_pool() [1/2]

os::rtos::memory_pool::memory_pool ( std::size_t  blocks,
std::size_t  block_size_bytes,
const attributes attr = initializer,
const allocator_type allocator = allocator_type () 
)
Parameters
[in]blocksThe maximum number of items in the pool.
[in]block_size_bytesThe size of an item, in bytes.
[in]attrReference to attributes.
[in]allocatorReference to allocator. Default a local temporary instance.

This constructor shall initialise a memory pool object with attributes referenced by attr. If the attributes specified by attr are modified later, the memory pool attributes shall not be affected. Upon successful initialisation, the state of the memory pool variable shall become initialised.

Only the memory pool itself may be used for allocations. It is not allowed to make copies of condition variable objects.

In cases where default memory pool attributes are appropriate, the variable memory_pool::initializer can be used to initialise condition variables. The effect shall be equivalent to creating a memory pool object with the simple constructor.

If the attributes define a storage area (via mp_pool_address and mp_pool_size_bytes), that storage is used, otherwise the storage is dynamically allocated using the RTOS specific allocator (rtos::memory::allocator).

If the attr attributes are modified after the memory_pool creation, the memory_pool attributes shall not be affected.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 231 of file os-mempool.cpp.

234 : memory_pool{ nullptr, blocks, block_size_bytes, attr, allocator }
235 {
236 }
memory_pool(std::size_t blocks, std::size_t block_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
Construct a memory pool object instance.
allocator_stateless_default_resource< T > allocator
Type of allocator used by the system objects. Must be stateless.
Definition os-types.h:53

◆ memory_pool() [2/2]

os::rtos::memory_pool::memory_pool ( const char *  name,
std::size_t  blocks,
std::size_t  block_size_bytes,
const attributes attr = initializer,
const allocator_type allocator = allocator_type () 
)
Parameters
[in]namePointer to name.
[in]blocksThe maximum number of items in the pool.
[in]block_size_bytesThe size of an item, in bytes.
[in]attrReference to attributes.
[in]allocatorReference to allocator. Default a local temporary instance.

This constructor shall initialise a named memory pool object with attributes referenced by attr. If the attributes specified by attr are modified later, the memory pool attributes shall not be affected. Upon successful initialisation, the state of the memory pool variable shall become initialised.

Only the memory pool itself may be used for allocations. It is not allowed to make copies of condition variable objects.

In cases where default memory pool attributes are appropriate, the variable memory_pool::initializer can be used to initialise condition variables. The effect shall be equivalent to creating a memory pool object with the simple constructor.

If the attributes define a storage area (via mp_pool_address and mp_pool_size_bytes), that storage is used, otherwise the storage is dynamically allocated using the RTOS specific allocator (rtos::memory::allocator).

If the attr attributes are modified after the memory_pool creation, the memory_pool attributes shall not be affected.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 266 of file os-mempool.cpp.

271 {
272#if defined(OS_TRACE_RTOS_MEMPOOL)
273 trace::printf ("%s() @%p %s %u %u\n", __func__, this, this->name (),
274 blocks, block_size_bytes);
275#endif
276
277 if (attr.mp_pool_address != nullptr)
278 {
279 // Do not use any allocator at all.
280 internal_construct_ (blocks, block_size_bytes, attr, nullptr, 0);
281 }
282 else
283 {
284 allocator_ = &allocator;
285
286 // If no user storage was provided via attributes,
287 // allocate it dynamically via the allocator.
288 allocated_pool_size_elements_
290 typename allocator_type::value_type> (blocks,
291 block_size_bytes)
292 + sizeof (typename allocator_type::value_type) - 1)
293 / sizeof (typename allocator_type::value_type);
294
295 allocated_pool_addr_
296 = const_cast<allocator_type&> (allocator).allocate (
297 allocated_pool_size_elements_);
298
299 internal_construct_ (
300 blocks, block_size_bytes, attr, allocated_pool_addr_,
301 allocated_pool_size_elements_
302 * sizeof (typename allocator_type::value_type));
303 }
304 }
object_named_system()
Construct a named system object instance.
Definition os-decls.h:760
const char * name(void) const
Get object name.
Definition os-decls.h:753
T value_type
Type of elements to be allocated.
Definition os-memory.h:543
memory::allocator< thread::stack::allocation_element_t > allocator_type
Default RTOS allocator.
Definition os-mempool.h:202
constexpr std::size_t compute_allocated_size_bytes(std::size_t blocks, std::size_t block_size_bytes)
Calculator for pool storage requirements.
Definition os-mempool.h:188
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59

References compute_allocated_size_bytes(), os::rtos::memory_pool::attributes::mp_pool_address, and os::trace::printf().

◆ ~memory_pool()

os::rtos::memory_pool::~memory_pool ( )
virtual

This destructor shall destroy the memory pool object; the object becomes, in effect, uninitialised. An implementation may cause the destructor to set the object to an invalid value.

It shall be safe to destroy an initialised memory pool object upon which no threads are currently blocked. Attempting to destroy a memory pool object upon which other threads are currently blocked results in undefined behaviour.

If the storage for the memory pool was dynamically allocated, it is deallocated using the same allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 400 of file os-mempool.cpp.

401 {
402#if defined(OS_TRACE_RTOS_MEMPOOL)
403 trace::printf ("%s() @%p %s\n", __func__, this, name ());
404#endif
405
406 // There must be no threads waiting for this pool.
407 assert (list_.empty ());
408
409 typedef typename std::allocator_traits<allocator_type>::pointer pointer;
410
411 if (allocated_pool_addr_ != nullptr)
412 {
413 static_cast<allocator_type*> (const_cast<void*> (allocator_))
414 ->deallocate (static_cast<pointer> (allocated_pool_addr_),
415 allocated_pool_size_elements_);
416 }
417 }

References os::rtos::memory::allocator_stateless_default_resource< T >::deallocate(), os::rtos::internal::object_named::name(), and os::trace::printf().

Member Function Documentation

◆ alloc()

void * os::rtos::memory_pool::alloc ( void  )
Parameters
None.
Returns
Pointer to memory block, or nullptr if interrupted.

The alloc() function shall allocate a fixed size memory block from the memory pool.

If the memory pool is empty, alloc() shall block until a block is freed or until alloc() is cancelled/interrupted. If more than one thread is waiting to allocate a block, when a block is freed and the Priority Scheduling option is supported, then the thread of highest priority that has been waiting the longest shall be selected to allocate the block. Otherwise, it is unspecified which waiting thread allocates the block.

This function uses a critical section to protect against simultaneous access from other threads or interrupts.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 510 of file os-mempool.cpp.

511 {
512#if defined(OS_TRACE_RTOS_MEMPOOL)
513 trace::printf ("%s() @%p %s\n", __func__, this, name ());
514#endif
515
516 // Don't call this from interrupt handlers.
518 // Don't call this from critical regions.
520
521 void* p;
522
523 // Extra test before entering the loop, with its inherent weight.
524 // Trade size for speed.
525 {
526 // ----- Enter critical section ---------------------------------------
527 interrupts::critical_section ics;
528
529 p = internal_try_first_ ();
530 if (p != nullptr)
531 {
532#if defined(OS_TRACE_RTOS_MEMPOOL)
533 trace::printf ("%s()=%p @%p %s\n", __func__, p, this, name ());
534#endif
535 return p;
536 }
537 // ----- Exit critical section ----------------------------------------
538 }
539
540 thread& crt_thread = this_thread::thread ();
541
542 // Prepare a list node pointing to the current thread.
543 // Do not worry for being on stack, it is temporarily linked to the
544 // list and guaranteed to be removed before this function returns.
545 internal::waiting_thread_node node{ crt_thread };
546
547 for (;;)
548 {
549 {
550 // ----- Enter critical section -----------------------------------
551 interrupts::critical_section ics;
552
553 p = internal_try_first_ ();
554 if (p != nullptr)
555 {
556#if defined(OS_TRACE_RTOS_MEMPOOL)
557 trace::printf ("%s()=%p @%p %s\n", __func__, p, this, name ());
558#endif
559 return p;
560 }
561
562 // Add this thread to the memory pool waiting list.
563 scheduler::internal_link_node (list_, node);
564 // state::suspended set in above link().
565 // ----- Exit critical section ------------------------------------
566 }
567
569
570 // Remove the thread from the memory pool waiting list,
571 // if not already removed by free().
572 scheduler::internal_unlink_node (node);
573
574 if (this_thread::thread ().interrupted ())
575 {
576#if defined(OS_TRACE_RTOS_MEMPOOL)
577 trace::printf ("%s() INTR @%p %s\n", __func__, this, name ());
578#endif
579 return nullptr;
580 }
581 }
582
583 /* NOTREACHED */
584 }
Standard thread.
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1101
bool locked(void)
Check if the scheduler is locked.
Definition os-sched.h:858
thread & thread(void)
Get the current running thread.
#define os_assert_throw(__e, __er)
Assert or throw a system error exception.
Definition os-decls.h:1122

References os::rtos::interrupts::in_handler_mode(), os::rtos::scheduler::locked(), os::rtos::internal::object_named::name(), os_assert_throw, os::trace::printf(), os::rtos::port::scheduler::reschedule(), and os::rtos::this_thread::thread().

Referenced by os::rtos::memory_pool_typed< T, Allocator >::alloc(), and os::rtos::memory_pool_inclusive< T, N >::alloc().

◆ block_size()

std::size_t os::rtos::memory_pool::block_size ( void  ) const
inline
Parameters
None.
Returns
The block size, in bytes.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 923 of file os-mempool.h.

924 {
925 return block_size_bytes_;
926 }

◆ capacity()

std::size_t os::rtos::memory_pool::capacity ( void  ) const
inline
Parameters
None.
Returns
The max number of blocks in the pool.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 914 of file os-mempool.h.

915 {
916 return blocks_;
917 }

Referenced by full().

◆ compute_allocated_size_bytes()

template<typename T >
constexpr std::size_t os::rtos::memory_pool::compute_allocated_size_bytes ( std::size_t  blocks,
std::size_t  block_size_bytes 
)
inlineconstexpr
Parameters
blocksNumber of blocks.
block_size_bytesSize of block.
Returns
Total required storage in bytes, including internal alignment.

Definition at line 188 of file os-mempool.h.

190 {
191 // Align each block
192 return (blocks
193 * ((block_size_bytes + (sizeof (T) - 1)) & ~(sizeof (T) - 1)));
194 }

Referenced by memory_pool(), and os::rtos::memory_pool_allocated< Allocator >::memory_pool_allocated().

◆ count()

std::size_t os::rtos::memory_pool::count ( void  ) const
inline
Parameters
None.
Returns
The number of blocks used from the queue.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 932 of file os-mempool.h.

933 {
934 return count_;
935 }

Referenced by empty(), and full().

◆ empty()

bool os::rtos::memory_pool::empty ( void  ) const
inline
Parameters
None
Return values
trueThe memory pool has no allocated blocks.
falseThe memory pool has allocated blocks.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 941 of file os-mempool.h.

942 {
943 return (count () == 0);
944 }
std::size_t count(void) const
Get blocks count.
Definition os-mempool.h:932

References count().

◆ free()

result_t os::rtos::memory_pool::free ( void *  block)
Parameters
[in]blockPointer to memory block to free.
Return values
result::okThe memory block was released.
EINVALThe block does not belong to the memory pool.

Return a memory block previously allocated by alloc() back to the memory pool.

It uses a critical section to protect simultaneous access from other threads or interrupts.

Note
Can be invoked from Interrupt Service Routines.

Definition at line 781 of file os-mempool.cpp.

782 {
783#if defined(OS_TRACE_RTOS_MEMPOOL)
784 trace::printf ("%s(%p) @%p %s\n", __func__, block, this, name ());
785#endif
786
787 // Don't call this from high priority interrupts.
788 assert (port::interrupts::is_priority_valid ());
789
790 // Validate pointer.
791#pragma GCC diagnostic push
792#if defined(__clang__)
793#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
794#endif
795 if ((block < pool_addr_)
796 || (block >= (static_cast<char*> (pool_addr_)
797 + blocks_ * block_size_bytes_)))
798 {
799#if defined(OS_TRACE_RTOS_MEMPOOL)
800 trace::printf ("%s(%p) EINVAL @%p %s\n", __func__, block, this,
801 name ());
802#endif
803 return EINVAL;
804 }
805#pragma GCC diagnostic pop
806
807 {
808 // ----- Enter critical section ---------------------------------------
809 interrupts::critical_section ics;
810
811 // Perform a push_front() on the single linked LIFO list,
812 // i.e. add the block to the beginning of the list.
813
814 // Link previous list to this block; may be null, but it does
815 // not matter.
816 *(static_cast<void**> (block)) = first_;
817
818 // Now this block is the first one.
819 first_ = block;
820
821#pragma GCC diagnostic push
822#if defined(__clang__)
823#pragma clang diagnostic ignored "-Wdeprecated-volatile"
824#elif defined(__GNUC__)
825#pragma GCC diagnostic ignored "-Wvolatile"
826#endif
827 --count_;
828#pragma GCC diagnostic pop
829
830 // ----- Exit critical section ----------------------------------------
831 }
832
833 // Wake-up one thread, if any.
834 list_.resume_one ();
835
836 return result::ok;
837 }
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:179

References os::rtos::internal::object_named::name(), os::rtos::result::ok, and os::trace::printf().

Referenced by os::rtos::memory_pool_typed< T, Allocator >::free(), and os::rtos::memory_pool_inclusive< T, N >::free().

◆ full()

bool os::rtos::memory_pool::full ( void  ) const
inline
Parameters
None.
Return values
trueAll memory blocks are allocated.
falseThere are still memory blocks that can be allocated.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 950 of file os-mempool.h.

951 {
952 return (count () == capacity ());
953 }
std::size_t capacity(void) const
Get memory pool capacity.
Definition os-mempool.h:914

References capacity(), and count().

◆ name()

const char * os::rtos::internal::object_named::name ( void  ) const
inlineinherited
Parameters
None.
Returns
A null terminated string.

All objects return a non-null string; anonymous objects return "-".

Note
Can be invoked from Interrupt Service Routines.

Definition at line 753 of file os-decls.h.

754 {
755 return name_;
756 }

Referenced by os::memory::lifo::lifo(), os::memory::malloc_memory_resource::malloc_memory_resource(), os::rtos::message_queue_typed< T, Allocator >::message_queue_typed(), os::memory::block_pool::~block_pool(), os::rtos::event_flags::~event_flags(), os::memory::first_fit_top::~first_fit_top(), os::memory::lifo::~lifo(), os::memory::malloc_memory_resource::~malloc_memory_resource(), ~memory_pool(), os::rtos::message_queue::~message_queue(), os::rtos::mutex::~mutex(), os::rtos::semaphore::~semaphore(), os::rtos::thread::~thread(), os::rtos::timer::~timer(), alloc(), os::rtos::thread::cancel(), os::rtos::event_flags::clear(), os::rtos::mutex::consistent(), os::rtos::thread::detach(), os::memory::new_delete_memory_resource::do_allocate(), os::memory::block_pool::do_allocate(), os::memory::first_fit_top::do_allocate(), os::memory::lifo::do_allocate(), os::memory::malloc_memory_resource::do_allocate(), os::rtos::thread::flags_raise(), free(), os::rtos::event_flags::get(), os::rtos::thread::interrupt(), os::rtos::thread::join(), os::rtos::thread::kill(), os::rtos::internal::terminated_threads_list::link(), os::rtos::mutex::lock(), os::rtos::memory::memory_resource::out_of_memory_handler(), os::rtos::semaphore::post(), os::rtos::mutex::prio_ceiling(), os::rtos::mutex::prio_ceiling(), os::rtos::thread::priority(), os::rtos::thread::priority_inherited(), os::rtos::event_flags::raise(), os::rtos::message_queue::receive(), reset(), os::rtos::message_queue::reset(), os::rtos::mutex::reset(), os::rtos::semaphore::reset(), os::rtos::thread::resume(), os::rtos::message_queue::send(), os::rtos::clock::sleep_for(), os::rtos::timer::start(), os::rtos::timer::stop(), timed_alloc(), os::rtos::mutex::timed_lock(), os::rtos::message_queue::timed_receive(), os::rtos::message_queue::timed_send(), os::rtos::semaphore::timed_wait(), os::rtos::event_flags::timed_wait(), os::rtos::memory::memory_resource::trace_print_statistics(), try_alloc(), os::rtos::mutex::try_lock(), os::rtos::message_queue::try_receive(), os::rtos::message_queue::try_send(), os::rtos::event_flags::try_wait(), os::rtos::semaphore::try_wait(), os::rtos::internal::ready_threads_list::unlink_head(), os::rtos::mutex::unlock(), os::rtos::event_flags::wait(), os::rtos::semaphore::wait(), and os::rtos::event_flags::waiting().

◆ operator delete()

void os::rtos::internal::object_named_system::operator delete ( void *  ptr,
std::size_t  bytes 
)
inlinestaticinherited
Parameters
ptrPointer to object.
bytesNumber of bytes to deallocate.
Returns
Nothing.

The deallocation function (3.7.4.2) called by a delete-expression to render the value of ptr invalid.

ptr shall be a null pointer or its value shall be a value returned by an earlier call to the (possibly replaced) operator new() which has not been invalidated by an intervening call to operator delete(void*).

If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the earlier call to operator new.

The storage is deallocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 120 of file os-inlines.h.

121 {
122 assert (!interrupts::in_handler_mode ());
123
124 rtos::memory::allocator<char> ().deallocate (static_cast<char*> (ptr),
125 bytes);
126 }

References os::rtos::memory::allocator_stateless_default_resource< T >::deallocate(), and os::rtos::interrupts::in_handler_mode().

◆ operator delete[]()

void os::rtos::internal::object_named_system::operator delete[] ( void *  ptr,
std::size_t  bytes 
)
inlinestaticinherited
Parameters
ptrPointer to array of objects.
bytesNumber of bytes to deallocate.
Returns
Nothing.

The deallocation function (3.7.4.2) called by the array form of a delete-expression to render the value of ptr invalid.

If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the earlier call to operator new.

The storage is deallocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 141 of file os-inlines.h.

142 {
143 // Forward array deallocation to single element deallocation.
144 operator delete (ptr, bytes);
145 }

◆ operator new() [1/2]

void * os::rtos::internal::object_named_system::operator new ( std::size_t  bytes)
inlinestaticinherited
Parameters
bytesNumber of bytes to allocate.
Returns
Pointer to allocated object.

The allocation function (3.7.4.1) called by a new-expression (5.3.4) to allocate a storage of size bytes suitably aligned to represent any object of that size. Return a non-null pointer to suitably aligned storage (3.7.4).

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 43 of file os-inlines.h.

44 {
45 assert (!interrupts::in_handler_mode ());
46
47 return rtos::memory::allocator<char> ().allocate (bytes);
48 }

References os::rtos::memory::allocator_stateless_default_resource< T >::allocate(), and os::rtos::interrupts::in_handler_mode().

◆ operator new() [2/2]

void * os::rtos::internal::object_named_system::operator new ( std::size_t  bytes,
void *  ptr 
)
inlinestaticinherited
Parameters
bytesNumber of bytes to emplace.
ptrPointer to location to emplace the object.
Returns
Pointer to emplaced object.

The allocation function (3.7.4.1) called by a placement new-expression to allocate a storage of size bytes suitably aligned to represent any object of that size. Return a non-null pointer to suitably aligned storage (3.7.4).

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 80 of file os-inlines.h.

81 {
82 return ptr;
83 }

◆ operator new[]() [1/2]

void * os::rtos::internal::object_named_system::operator new[] ( std::size_t  bytes)
inlinestaticinherited
Parameters
bytesNumber of bytes to allocate.
Returns
Pointer to allocated array.

The allocation function (3.7.4.1) called by the array form of a new-expression (5.3.4) to allocate a storage of size bytes suitably aligned to represent any array object of that size or smaller.

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 61 of file os-inlines.h.

62 {
63 // Forward array allocation to single element allocation.
64 return operator new (bytes);
65 }

◆ operator new[]() [2/2]

void * os::rtos::internal::object_named_system::operator new[] ( std::size_t  bytes,
void *  ptr 
)
inlinestaticinherited
Parameters
bytesNumber of bytes to emplace.
ptrPointer to location to emplace the object.
Returns
Pointer to emplaced array.

The allocation function (3.7.4.1) called by the array form of a placement new-expression to allocate a storage of size bytes suitably aligned to represent any array object of that size or smaller.

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 97 of file os-inlines.h.

98 {
99 // Forward array allocation to single element allocation.
100 return operator new (bytes, ptr);
101 }

◆ operator==()

bool os::rtos::memory_pool::operator== ( const memory_pool rhs) const
inline
Return values
trueThe given memory pool is the same as this memory pool.
falseThe memory pools are different.

Identical memory pools should have the same memory address.

Definition at line 905 of file os-mempool.h.

906 {
907 return this == &rhs;
908 }

◆ pool()

void * os::rtos::memory_pool::pool ( void  )
inline
Parameters
None.
Returns
Pointer to storage.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 959 of file os-mempool.h.

960 {
961 return pool_addr_;
962 }

◆ reset()

result_t os::rtos::memory_pool::reset ( void  )
Parameters
None.
Return values
result::okThe memory pool was reset.
EPERMCannot be invoked from an Interrupt Service Routines.

Reset the memory pool to the initial state, with all blocks free.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 846 of file os-mempool.cpp.

847 {
848#if defined(OS_TRACE_RTOS_MEMPOOL)
849 trace::printf ("%s() @%p %s\n", __func__, this, name ());
850#endif
851
852 // Don't call this from interrupt handlers.
854
855 {
856 // ----- Enter critical section ---------------------------------------
857 interrupts::critical_section ics;
858
859 internal_init_ ();
860 // ----- Exit critical section ----------------------------------------
861 }
862
863 // Wake-up all threads, if any.
864 // Need not be inside the critical section,
865 // the list is protected by inner `resume_one()`.
866 list_.resume_all ();
867
868 return result::ok;
869 }
#define os_assert_err(__e, __er)
Assert or return an error.
Definition os-decls.h:1101

References os::rtos::interrupts::in_handler_mode(), os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, and os::trace::printf().

◆ timed_alloc()

void * os::rtos::memory_pool::timed_alloc ( clock::duration_t  timeout)
Parameters
[in]timeoutTimeout to wait, in clock units (ticks or seconds).
Returns
Pointer to memory block, or nullptr if timeout.

The timed_alloc() function shall allocate a fixed size memory block from the memory pool.

If the memory pool is empty, timed_alloc() shall block until a block is freed or until timed_alloc() is cancelled/interrupted. If more than one thread is waiting to allocate a block, when a block is freed and the Priority Scheduling option is supported, then the thread of highest priority that has been waiting the longest shall be selected to allocate the block. Otherwise, it is unspecified which waiting thread allocates the block.

The timed_alloc() function shall allocate any of the available blocks, regardless of their age and the order they were freed. However, if no blocks are available, the wait for such a block shall be terminated when the specified timeout expires.

The timeout shall expire after the number of time units (that is when the value of that clock equals or exceeds (now()+duration). The resolution of the timeout shall be the resolution of the clock on which it is based.

Under no circumstance shall the operation fail with a timeout if a block can be allocated from the memory pool immediately. The validity of the timeout need not be checked if the block can be allocated immediately.

The clock used for timeouts can be specified via the clock attribute. By default, the clock derived from the scheduler timer is used, and the durations are expressed in ticks.

This function uses a critical section to protect against simultaneous access from other threads or interrupts.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 669 of file os-mempool.cpp.

670 {
671#if defined(OS_TRACE_RTOS_MEMPOOL)
672#pragma GCC diagnostic push
673#if defined(__clang__)
674#elif defined(__GNUC__)
675#pragma GCC diagnostic ignored "-Wuseless-cast"
676#endif
677 trace::printf ("%s(%u) @%p %s\n", __func__,
678 static_cast<unsigned int> (timeout), this, name ());
679#pragma GCC diagnostic pop
680#endif
681
682 // Don't call this from interrupt handlers.
684 // Don't call this from critical regions.
686
687 void* p;
688
689 // Extra test before entering the loop, with its inherent weight.
690 // Trade size for speed.
691 {
692 // ----- Enter critical section ---------------------------------------
693 interrupts::critical_section ics;
694
695 p = internal_try_first_ ();
696 if (p != nullptr)
697 {
698#if defined(OS_TRACE_RTOS_MEMPOOL)
699 trace::printf ("%s()=%p @%p %s\n", __func__, p, this, name ());
700#endif
701 return p;
702 }
703 // ----- Exit critical section ----------------------------------------
704 }
705
706 thread& crt_thread = this_thread::thread ();
707
708 // Prepare a list node pointing to the current thread.
709 // Do not worry for being on stack, it is temporarily linked to the
710 // list and guaranteed to be removed before this function returns.
711 internal::waiting_thread_node node{ crt_thread };
712
713 internal::clock_timestamps_list& clock_list = clock_->steady_list ();
714 clock::timestamp_t timeout_timestamp = clock_->steady_now () + timeout;
715
716 // Prepare a timeout node pointing to the current thread.
717 internal::timeout_thread_node timeout_node{ timeout_timestamp,
718 crt_thread };
719
720 for (;;)
721 {
722 {
723 // ----- Enter critical section -----------------------------------
724 interrupts::critical_section ics;
725
726 p = internal_try_first_ ();
727 if (p != nullptr)
728 {
729#if defined(OS_TRACE_RTOS_MEMPOOL)
730 trace::printf ("%s()=%p @%p %s\n", __func__, p, this, name ());
731#endif
732 return p;
733 }
734
735 // Add this thread to the memory pool waiting list,
736 // and the clock timeout list.
737 scheduler::internal_link_node (list_, node, clock_list,
738 timeout_node);
739 // state::suspended set in above link().
740 // ----- Exit critical section ------------------------------------
741 }
742
744
745 // Remove the thread from the memory pool waiting list,
746 // if not already removed by free() and from the clock
747 // timeout list, if not already removed by the timer.
748 scheduler::internal_unlink_node (node, timeout_node);
749
750 if (this_thread::thread ().interrupted ())
751 {
752#if defined(OS_TRACE_RTOS_MEMPOOL)
753 trace::printf ("%s() INTR @%p %s\n", __func__, this, name ());
754#endif
755 return nullptr;
756 }
757
758 if (clock_->steady_now () >= timeout_timestamp)
759 {
760#if defined(OS_TRACE_RTOS_MEMPOOL)
761 trace::printf ("%s() TMO @%p %s\n", __func__, this, name ());
762#endif
763 return nullptr;
764 }
765 }
766
767 /* NOTREACHED */
768 }
port::clock::timestamp_t timestamp_t
Type of variables holding clock time stamps.
Definition os-clocks.h:88

References os::rtos::interrupts::in_handler_mode(), os::rtos::scheduler::locked(), os::rtos::internal::object_named::name(), os_assert_throw, os::trace::printf(), os::rtos::port::scheduler::reschedule(), and os::rtos::this_thread::thread().

Referenced by os::rtos::memory_pool_typed< T, Allocator >::timed_alloc(), and os::rtos::memory_pool_inclusive< T, N >::timed_alloc().

◆ try_alloc()

void * os::rtos::memory_pool::try_alloc ( void  )
Parameters
None.
Returns
Pointer to memory block, or nullptr if no memory available.

Try to allocate a fixed size memory block from the memory pool, if available, return it, otherwise return nullptr.

The timed_alloc() function shall try to allocate a fixed size memory block from the memory pool.

If the memory pool is empty, timed_alloc() shall immediately return 'nullptr'.

This function uses a critical section to protect against simultaneous access from other threads or interrupts.

Note
Can be invoked from Interrupt Service Routines.

Definition at line 604 of file os-mempool.cpp.

605 {
606#if defined(OS_TRACE_RTOS_MEMPOOL)
607 trace::printf ("%s() @%p %s\n", __func__, this, name ());
608#endif
609
610 // Don't call this from high priority interrupts.
611 assert (port::interrupts::is_priority_valid ());
612
613 void* p;
614 {
615 // ----- Enter critical section ---------------------------------------
616 interrupts::critical_section ics;
617
618 p = internal_try_first_ ();
619 // ----- Exit critical section ----------------------------------------
620 }
621
622#if defined(OS_TRACE_RTOS_MEMPOOL)
623 trace::printf ("%s()=%p @%p %s\n", __func__, p, this, name ());
624#endif
625 return p;
626 }

References os::rtos::internal::object_named::name(), and os::trace::printf().

Referenced by os::rtos::memory_pool_typed< T, Allocator >::try_alloc(), and os::rtos::memory_pool_inclusive< T, N >::try_alloc().


The documentation for this class was generated from the following files: