28 #ifndef CMSIS_PLUS_RTOS_OS_MEMORY_H_ 29 #define CMSIS_PLUS_RTOS_OS_MEMORY_H_ 33 #if defined(__cplusplus) 64 class critical_section;
74 max (std::size_t a, std::size_t b)
76 return (a >= b) ? a : b;
86 align_size (std::size_t size, std::size_t align) noexcept
88 return ((size) + (align) - 1L) & ~((align) - 1L);
162 static constexpr std::size_t max_align =
alignof(std::max_align_t);
221 allocate (std::size_t bytes, std::size_t alignment = max_align);
232 deallocate (
void* addr, std::size_t bytes, std::size_t alignment =
252 reset (
void) noexcept;
262 coalesce (
void) noexcept;
271 max_size (
void)
const noexcept;
288 out_of_memory_handler (
void);
304 allocated_bytes (
void);
313 max_allocated_bytes (
void);
331 allocated_chunks (
void);
358 deallocations (
void);
368 trace_print_statistics (
void);
388 do_allocate (std::size_t bytes, std::size_t alignment) = 0;
399 do_deallocate (
void* addr, std::size_t bytes, std::size_t alignment)
418 do_max_size (
void)
const noexcept;
428 do_reset (
void) noexcept;
438 do_coalesce (
void) noexcept;
447 internal_increase_allocated_statistics (std::size_t bytes) noexcept;
456 internal_decrease_allocated_statistics (std::size_t bytes) noexcept;
470 std::size_t total_bytes_ = 0;
471 std::size_t allocated_bytes_ = 0;
472 std::size_t free_bytes_ = 0;
473 std::size_t allocated_chunks_ = 0;
474 std::size_t free_chunks_ = 0;
475 std::size_t max_allocated_bytes_ = 0;
476 std::size_t allocations_ = 0;
477 std::size_t deallocations_ = 0;
621 allocate (
std::
size_t elements);
631 deallocate (
value_type* addr,
std::
size_t elements) noexcept;
639 max_size (
void) const noexcept;
672 template<typename T, typename L, F get_resource>
689 allocator_stateless_polymorphic_synchronized () noexcept;
695 allocator_stateless_polymorphic_synchronized (
696 allocator_stateless_polymorphic_synchronized const & other) = default;
703 allocator_stateless_polymorphic_synchronized (
704 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & other)
711 allocator_stateless_polymorphic_synchronized (
712 allocator_stateless_polymorphic_synchronized && other) = default;
717 ~allocator_stateless_polymorphic_synchronized () = default;
733 allocator_stateless_polymorphic_synchronized&
734 operator= (allocator_stateless_polymorphic_synchronized const & other) = default;
741 allocator_stateless_polymorphic_synchronized&
742 operator= (allocator_stateless_polymorphic_synchronized && other) = default;
776 allocate (std::size_t elements);
786 deallocate (
value_type* addr, std::size_t elements) noexcept;
794 max_size (
void)
const noexcept;
797 allocator_stateless_polymorphic_synchronized
798 select_on_container_copy_construction (
void)
const noexcept;
801 resource (
void)
const noexcept;
814 template<
typename T1,
typename T2,
typename L, F get_resource>
820 get_resource>& rhs) noexcept;
822 template<
typename T1,
typename T2,
typename L, F get_resource>
828 get_resource>& rhs) noexcept;
855 using pointer =
typename allocator_traits::pointer;
914 operator() (
pointer addr)
const;
943 template<
typename T,
typename A,
typename ... Args>
1064 template<
typename T,
typename U = T>
1075 template<
typename T,
typename U = T>
1076 using unique_ptr = std::unique_ptr<T, allocator_deleter<allocator_typed<T, U>>>;
1143 return resource_thread;
1158 return resource_condition_variable;
1173 return resource_event_flags;
1188 return resource_memory_pool;
1203 return resource_message_queue;
1218 return resource_mutex;
1233 return resource_semaphore;
1248 return resource_timer;
1308 std::size_t alignment) noexcept
1381 out_of_memory_handler_ = handler;
1395 return out_of_memory_handler_;
1401 return total_bytes_;
1407 return allocated_bytes_;
1413 return max_allocated_bytes_;
1425 return allocated_chunks_;
1431 return free_chunks_;
1437 return allocations_;
1443 return deallocations_;
1451 "\ttotal: %u bytes, \n" 1452 "\tallocated: %u bytes in %u chunk(s), \n" 1453 "\tfree: %u bytes in %u chunk(s), \n" 1454 "\tmax: %u bytes, \n" 1455 "\tcalls: %u allocs, %u deallocs\n",
1468 return &lhs == &rhs || lhs.is_equal (rhs);
1474 return !(lhs == rhs);
1479 template<
typename T>
1480 template<
typename U>
1488 template<
typename T>
1498 template<
typename T>
1501 value_type* addr, std::size_t elements) noexcept
1509 template<
typename T>
1518 template<
typename T,
typename U,
typename L, F get_resource>
1524 return *lhs.resource () == *rhs.resource ();
1527 template<
typename T,
typename U,
typename L, F get_resource>
1533 return !(lhs == rhs);
1538 template<
typename T,
typename L, F get_resource>
1542 trace::printf (
"%s() @%p %p\n", __func__,
this, get_resource ());
1545 template<
typename T,
typename L, F get_resource>
1546 template<
typename U>
1554 template<
typename T,
typename L, F get_resource>
1557 std::size_t elements)
1563 if ((ms > 0) && (elements >
max_size ()))
1567 "allocator_stateless_polymorphic_synchronized<T>::allocate(size_t n)" 1568 " 'n' exceeds maximum supported size");
1573 std::lock_guard<locker_type> ulk
1576 return static_cast<value_type*
> (get_resource ()->allocate (
1580 template<
typename T,
typename L, F get_resource>
1583 value_type* addr, std::size_t elements) noexcept
1585 trace::printf (
"%s(%p,%u) @%p\n", __func__, addr, elements,
this);
1596 std::lock_guard<locker_type> ulk
1599 get_resource ()->deallocate (addr, elements *
sizeof(
value_type),
1603 template<
typename T,
typename L, F get_resource>
1606 void)
const noexcept
1608 return get_resource ()->max_size () /
sizeof(T);
1612 template<
typename T,
typename L, F get_resource>
1615 void)
const noexcept
1620 template<
typename T,
typename L, F get_resource>
1623 void)
const noexcept
1625 return get_resource ();
1631 template<
typename A>
1638 template<
typename A>
1654 template<
typename A>
1664 allocator_traits::destroy (alloc, std::addressof (*addr));
1668 allocator_traits::deallocate (alloc, addr, 1);
1684 template<
typename T,
typename A,
typename ... Args>
1698 static_assert(std::is_same<
typename allocator_traits::value_type, std::remove_cv_t<T>>::value
1699 || std::is_base_of<
typename allocator_traits::value_type, std::remove_cv_t<T>>::value,
1700 "Allocator must be of same type or derived.");
1702 static_assert(
sizeof(T) <=
sizeof(
typename allocator_traits::value_type),
1703 "Derived type must not be larger.");
1709 auto p = allocator_traits::allocate (alloc, 1);
1711 #if defined(__EXCEPTIONS) 1716 allocator_traits::construct (alloc, std::addressof (*p),
1717 std::forward<Args>(args)...);
1723 return std::unique_ptr<T, D> (p, D (alloc));
1727 allocator_traits::deallocate (alloc, p, 1);
1734 allocator_traits::construct (alloc, std::addressof (*p),
1735 std::forward<Args>(args)...);
1741 return std::unique_ptr<T, D> (p, D (alloc));
Memory resource manager (abstract class).
memory_resource * set_resource_typed< mutex >(memory_resource *res) noexcept
std::size_t allocations(void)
Get the number of allocations.
memory_resource * get_resource_typed< condition_variable >(void) noexcept
memory_resource * set_resource_typed< message_queue >(memory_resource *res) noexcept
std::size_t max_size(void) const noexcept
The maximum number of elements that can be passed to allocate().
virtual bool do_coalesce(void) noexcept
Implementation of the function to coalesce free blocks.
memory_resource * get_resource_typed< thread >(void) noexcept
virtual void do_reset(void) noexcept
Implementation of the function to reset the memory manager.
std::size_t allocated_bytes(void)
Get the current size of all allocated chunks.
rtos::memory::memory_resource memory_resource
auto allocate_unique(const A &allocator, Args &&... args)
Function template to allocate a unique pointer.
value_type * allocate(std::size_t elements)
Allocate a number of memory blocks of type value_type.
constexpr std::size_t max(std::size_t a, std::size_t b)
std::allocator_traits< A > allocator_traits
Standard allocator traits definition.
void deallocate(value_type *addr, std::size_t elements) noexcept
Deallocate the number of memory blocks of type value_type.
Allocator using memory resources.
memory_resource * get_resource_typed< mutex >(void) noexcept
void operator()(pointer addr) const
Function operator.
virtual void * do_allocate(std::size_t bytes, std::size_t alignment)=0
Implementation of the memory allocator.
std::size_t allocated_chunks(void)
Get the current number of allocated chunks.
allocator_stateless_polymorphic_synchronized() noexcept
Default constructor. Construct a default allocator object instance.
allocator_deleter()
Default constructor.
value_type * allocate(std::size_t elements)
Allocate a number of memory blocks of type value_type.
memory_resource * set_resource_typed< condition_variable >(memory_resource *res) noexcept
out_of_memory_handler_t out_of_memory_handler(void)
Get the out of memory handler.
void trace_print_statistics(void)
Print a long message with usage statistics.
bool is_equal(memory_resource const &other) const noexcept
Compare for equality with another memory_resource.
void deallocate(value_type *addr, std::size_t elements) noexcept
Deallocate the number of memory blocks of type value_type.
memory_resource * get_default_resource(void) noexcept
Get the default RTOS system memory manager.
std::size_t max_allocated_bytes(void)
Get the maximum allocated size.
Define a rebind template.
Scheduler critical section RAII helper.
constexpr std::size_t align_size(std::size_t size, std::size_t align) noexcept
Helper function to align size values.
memory_resource * set_resource_typed< semaphore >(memory_resource *res) noexcept
memory_resource * set_default_resource(memory_resource *res) noexcept
Set the default RTOS system memory manager.
const char * name(void) const
Get object name.
memory_resource * set_resource_typed< timer >(memory_resource *res) noexcept
memory_resource * set_resource_typed< memory_pool >(memory_resource *res) noexcept
std::size_t max_size(void) const noexcept
Get the largest value that can be passed to allocate().
std::unique_ptr< T, allocator_deleter< allocator_typed< T, U > >> unique_ptr
Type of a RTOS unique pointer to objects of type T.
memory_resource * set_resource_typed(memory_resource *res) noexcept
Function template to set a memory resource.
virtual bool do_is_equal(memory_resource const &other) const noexcept
Implementation of the equality comparator.
A allocator_type
Standard allocator type definition.
bool operator!=(thread::id x, thread::id y) noexcept
memory_resource * get_resource_typed< timer >(void) noexcept
memory_resource * get_resource_typed< semaphore >(void) noexcept
Base class for named objects.
void init_once_default_resource(void)
int printf(const char *format,...)
Write a formatted string to the trace device.
bool operator!=(const memory_resource &lhs, const memory_resource &rhs) noexcept
Compare the memory_resource instances for inequality.
std::size_t free_bytes(void)
Get the current size of all free chunks.
void * allocate(std::size_t bytes, std::size_t alignment=max_align)
Allocate a memory block.
typename allocator_traits::pointer pointer
virtual void do_deallocate(void *addr, std::size_t bytes, std::size_t alignment) noexcept=0
Implementation of the memory deallocator.
bool operator==(const memory_resource &lhs, const memory_resource &rhs) noexcept
Compare the memory_resource instances for equality.
bool coalesce(void) noexcept
Coalesce free blocks.
T value_type
Type of elements to be allocated.
allocator_stateless_default_resource() noexcept=default
Default constructor. Construct a default resource allocator object instance.
void __throw_system_error(int ev, const char *what_arg)
memory_resource * set_resource_typed< event_flags >(memory_resource *res) noexcept
memory_resource * get_resource_typed< memory_pool >(void) noexcept
std::size_t total_bytes(void)
Get the total size of managed memory.
memory_resource * default_resource
memory_resource * malloc_resource(void) noexcept
Get the address of a memory manager based on POSIX malloc().
virtual std::size_t do_max_size(void) const noexcept
Implementation of the function to get max size.
void reset(void) noexcept
Reset the memory manager to the initial state.
memory_resource * get_resource_typed< event_flags >(void) noexcept
memory_resource * get_resource_typed< message_queue >(void) noexcept
void deallocate(void *addr, std::size_t bytes, std::size_t alignment=max_align) noexcept
Deallocate the previously allocated memory block.
Standard allocator based on the RTOS system default memory manager.
std::size_t free_chunks(void)
Get the current number of free chunks.
bool operator==(thread::id x, thread::id y) noexcept
memory_resource * get_resource_typed(void) noexcept
Function template to get a memory resource.
void(*)(void) out_of_memory_handler_t
Type of out of memory handler.
void __throw_bad_alloc(void)
USB switch to High Speed occurred.
memory_resource * set_resource_typed< thread >(memory_resource *res) noexcept
std::size_t max_size(void) const noexcept
The maximum number of elements that can be passed to allocate().
std::size_t deallocations(void)
Get the number of deallocations.