µ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-memory.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2016-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#ifndef CMSIS_PLUS_RTOS_OS_MEMORY_H_
13#define CMSIS_PLUS_RTOS_OS_MEMORY_H_
14
15// ----------------------------------------------------------------------------
16
17#if defined(__cplusplus)
18
19// ----------------------------------------------------------------------------
20
22
23#include <limits>
24#include <new>
25#include <cerrno>
26#include <mutex>
27
28// ----------------------------------------------------------------------------
29
30// These definitions refer only to the RTOS allocators.
31// The application should use the similar ones from the
32// os::estd:: namespace.
33
34#pragma GCC diagnostic push
35#if defined(__clang__)
36#pragma clang diagnostic ignored "-Wc++98-compat"
37#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
38#endif
39
40// ----------------------------------------------------------------------------
41
42namespace os
43{
44 namespace estd
45 {
46#pragma GCC diagnostic push
47#if defined(__clang__)
48#pragma clang diagnostic ignored "-Wreserved-identifier"
49#endif
50 [[noreturn]] void
51 __throw_bad_alloc (void);
52#pragma GCC diagnostic pop
53
54 template <typename L>
56
57 } // namespace estd
58
59 namespace rtos
60 {
61 namespace scheduler
62 {
63 class critical_section;
64 }
65
66 class null_locker;
67
68 namespace memory
69 {
70 // ----------------------------------------------------------------------
71
72 constexpr std::size_t
73 max (std::size_t a, std::size_t b)
74 {
75 return (a >= b) ? a : b;
76 }
77
84 constexpr std::size_t
85 align_size (std::size_t size, std::size_t align) noexcept
86 {
87 return ((size) + (align)-1L) & ~((align)-1L);
88 }
89
90 class memory_resource;
91
92 // ----------------------------------------------------------------------
93
110 memory_resource*
111 malloc_resource (void) noexcept;
112
118 memory_resource*
119 set_default_resource (memory_resource* res) noexcept;
120
127 memory_resource*
128 get_default_resource (void) noexcept;
129
130 void
132
137 // ======================================================================
141 using out_of_memory_handler_t = void (*) (void);
142
152#pragma GCC diagnostic push
153#if defined(__clang__)
154#elif defined(__GNUC__)
155#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
156#pragma GCC diagnostic ignored "-Wsuggest-final-types"
157#endif
159 {
160
161 public:
166 static constexpr std::size_t max_align = alignof (std::max_align_t);
167
177 memory_resource () = default;
178
183 memory_resource (const char* name);
184
189 // The rule of five.
190 memory_resource (const memory_resource&) = delete;
191 memory_resource (memory_resource&&) = delete;
193 operator= (const memory_resource&)
194 = delete;
196 operator= (memory_resource&&)
197 = delete;
198
206 virtual ~memory_resource ();
207
212 public:
224 void*
225 allocate (std::size_t bytes, std::size_t alignment = max_align);
226
235 void
236 deallocate (void* addr, std::size_t bytes,
237 std::size_t alignment = max_align) noexcept;
238
245 bool
246 is_equal (memory_resource const& other) const noexcept;
247
255 void
256 reset (void) noexcept;
257
265 bool
266 coalesce (void) noexcept;
267
274 std::size_t
275 max_size (void) const noexcept;
276
284
293
298 std::size_t
299 total_bytes (void);
300
307 std::size_t
308 allocated_bytes (void);
309
316 std::size_t
317 max_allocated_bytes (void);
318
325 std::size_t
326 free_bytes (void);
327
334 std::size_t
335 allocated_chunks (void);
336
343 std::size_t
344 free_chunks (void);
345
352 std::size_t
353 allocations (void);
354
361 std::size_t
362 deallocations (void);
363
371 void
373
378 protected:
390 virtual void*
391 do_allocate (std::size_t bytes, std::size_t alignment)
392 = 0;
393
402 virtual void
403 do_deallocate (void* addr, std::size_t bytes,
404 std::size_t alignment) noexcept
405 = 0;
406
413 virtual bool
414 do_is_equal (memory_resource const& other) const noexcept;
415
422 virtual std::size_t
423 do_max_size (void) const noexcept;
424
432 virtual void
433 do_reset (void) noexcept;
434
442 virtual bool
443 do_coalesce (void) noexcept;
444
451 void
452 internal_increase_allocated_statistics (std::size_t bytes) noexcept;
453
460 void
461 internal_decrease_allocated_statistics (std::size_t bytes) noexcept;
462
467 protected:
472 out_of_memory_handler_t out_of_memory_handler_ = nullptr;
473
474 std::size_t total_bytes_ = 0;
475 std::size_t allocated_bytes_ = 0;
476 std::size_t free_bytes_ = 0;
477 std::size_t allocated_chunks_ = 0;
478 std::size_t free_chunks_ = 0;
479 std::size_t max_allocated_bytes_ = 0;
480 std::size_t allocations_ = 0;
481 std::size_t deallocations_ = 0;
482
486 };
487#pragma GCC diagnostic pop
488
502 bool
503 operator== (const memory_resource& lhs,
504 const memory_resource& rhs) noexcept;
505
513 bool
514 operator!= (const memory_resource& lhs,
515 const memory_resource& rhs) noexcept;
516
521 // ======================================================================
536 template <typename T>
538 {
539 public:
543 using value_type = T;
544
555
562 = default;
563
568 template <typename U>
570 allocator_stateless_default_resource<U> const& other) noexcept;
571
578 = default;
579
584
601 = default;
602
610 = default;
611
616 public:
628 allocate (std::size_t elements);
629
637 void
638 deallocate (value_type* addr, std::size_t elements) noexcept;
639
645 std::size_t
646 max_size (void) const noexcept;
647
652 protected:
653 // This class should have no member variables, to meet the
654 // default allocator stateless requirements.
655 };
656
657 // ======================================================================
658
663 template <typename L>
664 class lock_guard;
665
666 using F = memory_resource*(void);
667
679 template <typename T, typename L, F get_resource>
681 {
682 public:
683 using value_type = T;
684 using locker_type = L;
685
696
703 = default;
704
709 template <typename U>
712 U, L, get_resource> const& other) noexcept;
713
720 = default;
721
726
743 = default;
744
752 = default;
753
758 public:
774 template <typename U>
775 struct rebind
776 {
777 using other
779 get_resource>;
780 };
781
788 allocate (std::size_t elements);
789
797 void
798 deallocate (value_type* addr, std::size_t elements) noexcept;
799
805 std::size_t
806 max_size (void) const noexcept;
807
808#if 0
810 select_on_container_copy_construction (void) const noexcept;
811
813 resource (void) const noexcept;
814#endif
815
820 private:
821 // This class should have no member variables, to meet the
822 // default allocator stateless requirements.
823 };
824
825 template <typename T1, typename T2, typename L, F get_resource>
826 bool
828 T1, L, get_resource>& lhs,
830 T2, L, get_resource>& rhs) noexcept;
831
832 template <typename T1, typename T2, typename L, F get_resource>
833 bool
835 T1, L, get_resource>& lhs,
837 T2, L, get_resource>& rhs) noexcept;
838
849 template <typename A>
851 {
852 public:
856 using allocator_type = A;
857
861 using allocator_traits = std::allocator_traits<A>;
862
863 using pointer = typename allocator_traits::pointer;
864
874
880
886
890 ~allocator_deleter () = default;
891
907 operator= (const allocator_deleter& other)
908 = default;
909
916 operator= (allocator_deleter&& other)
917 = default;
918
919 // /**
920 // * @brief Function operator.
921 // * @param addr Pointer to memory to deallocate.
922 // */
923 void
924 operator() (pointer addr) const;
925
930 protected:
936
940 };
941
952 template <typename T, typename A, typename... Args>
953 auto
954 allocate_unique (const A& allocator, Args&&... args);
955
956 // ----------------------------------------------------------------------
957
968 template <typename T>
971
976 template <typename T>
978 get_resource_typed (void) noexcept;
979
980 // ----------------------------------------------------------------------
981
982 template <>
985
986 template <>
988 get_resource_typed<thread> (void) noexcept;
989
990 // ----------------------------------------------------------------------
991
992 template <>
995
996 template <>
999
1000 // ----------------------------------------------------------------------
1001
1002 template <>
1005
1006 template <>
1008 get_resource_typed<event_flags> (void) noexcept;
1009
1010 // ----------------------------------------------------------------------
1011
1012 template <>
1015
1016 template <>
1018 get_resource_typed<memory_pool> (void) noexcept;
1019
1020 // ----------------------------------------------------------------------
1021
1022 template <>
1025
1026 template <>
1028 get_resource_typed<message_queue> (void) noexcept;
1029
1030 // ----------------------------------------------------------------------
1031
1032 template <>
1035
1036 template <>
1038 get_resource_typed<mutex> (void) noexcept;
1039
1040 // ----------------------------------------------------------------------
1041
1042 template <>
1045
1046 template <>
1048 get_resource_typed<semaphore> (void) noexcept;
1049
1050 // ----------------------------------------------------------------------
1051
1052 template <>
1055
1056 template <>
1058 get_resource_typed<timer> (void) noexcept;
1059
1064 // ----------------------------------------------------------------------
1073 template <typename T, typename U = T>
1075 T, scheduler::lockable, get_resource_typed<U>>;
1076
1085 template <typename T, typename U = T>
1087 = std::unique_ptr<T, allocator_deleter<allocator_typed<T, U>>>;
1088
1093 // ----------------------------------------------------------------------
1094 } /* namespace memory */
1095 } /* namespace rtos */
1096} /* namespace os */
1097
1098// ===== Inline & template implementations ====================================
1099
1100namespace os
1101{
1102 namespace rtos
1103 {
1104 namespace memory
1105 {
1106 // ----------------------------------------------------------------------
1107
1112 extern memory_resource* default_resource;
1113
1114 extern memory_resource* resource_thread;
1115 extern memory_resource* resource_condition_variable;
1116 extern memory_resource* resource_event_flags;
1117 extern memory_resource* resource_memory_pool;
1118 extern memory_resource* resource_message_queue;
1119 extern memory_resource* resource_mutex;
1120 extern memory_resource* resource_semaphore;
1121 extern memory_resource* resource_timer;
1122
1127 // ----------------------------------------------------------------------
1135 inline memory_resource*
1136 get_default_resource (void) noexcept
1137 {
1139 return default_resource;
1140 }
1141
1149 template <>
1151 get_resource_typed<thread> (void) noexcept
1152 {
1154 return resource_thread;
1155 }
1156
1164 template <>
1167 {
1169 return resource_condition_variable;
1170 }
1171
1179 template <>
1181 get_resource_typed<event_flags> (void) noexcept
1182 {
1184 return resource_event_flags;
1185 }
1186
1194 template <>
1196 get_resource_typed<memory_pool> (void) noexcept
1197 {
1199 return resource_memory_pool;
1200 }
1201
1209 template <>
1211 get_resource_typed<message_queue> (void) noexcept
1212 {
1214 return resource_message_queue;
1215 }
1216
1224 template <>
1226 get_resource_typed<mutex> (void) noexcept
1227 {
1229 return resource_mutex;
1230 }
1231
1239 template <>
1241 get_resource_typed<semaphore> (void) noexcept
1242 {
1244 return resource_semaphore;
1245 }
1246
1254 template <>
1256 get_resource_typed<timer> (void) noexcept
1257 {
1259 return resource_timer;
1260 }
1261
1262 // ======================================================================
1263
1264 inline memory_resource::memory_resource (const char* name)
1265 : object_named{ name }
1266 {
1267 }
1268
1289 inline void*
1290 memory_resource::allocate (std::size_t bytes, std::size_t alignment)
1291 {
1292 ++allocations_;
1293 return do_allocate (bytes, alignment);
1294 }
1295
1311 inline void
1312 memory_resource::deallocate (void* addr, std::size_t bytes,
1313 std::size_t alignment) noexcept
1314 {
1315 ++deallocations_;
1316 do_deallocate (addr, bytes, alignment);
1317 }
1318
1330 inline bool
1331 memory_resource::is_equal (memory_resource const& other) const noexcept
1332 {
1333 return do_is_equal (other);
1334 }
1335
1339 inline std::size_t
1340 memory_resource::max_size (void) const noexcept
1341 {
1342 return do_max_size ();
1343 }
1344
1348 inline void
1350 {
1351 do_reset ();
1352 }
1353
1364 inline bool
1366 {
1367 return do_coalesce ();
1368 }
1369
1376 {
1377 trace::printf ("%s(%p) @%p %s\n", __func__, handler, this, name ());
1378
1379 out_of_memory_handler_t tmp = out_of_memory_handler_;
1380 out_of_memory_handler_ = handler;
1381
1382 return tmp;
1383 }
1384
1391 {
1392 return out_of_memory_handler_;
1393 }
1394
1395 inline std::size_t
1397 {
1398 return total_bytes_;
1399 }
1400
1401 inline std::size_t
1403 {
1404 return allocated_bytes_;
1405 }
1406
1407 inline std::size_t
1409 {
1410 return max_allocated_bytes_;
1411 }
1412
1413 inline std::size_t
1415 {
1416 return free_bytes_;
1417 }
1418
1419 inline std::size_t
1421 {
1422 return allocated_chunks_;
1423 }
1424
1425 inline std::size_t
1427 {
1428 return free_chunks_;
1429 }
1430
1431 inline std::size_t
1433 {
1434 return allocations_;
1435 }
1436
1437 inline std::size_t
1439 {
1440 return deallocations_;
1441 }
1442
1443 inline void
1445 {
1446#if defined(TRACE)
1447 trace::printf ("Memory '%s' @%p: \n"
1448 "\ttotal: %u bytes, \n"
1449 "\tallocated: %u bytes in %u chunk(s), \n"
1450 "\tfree: %u bytes in %u chunk(s), \n"
1451 "\tmax: %u bytes, \n"
1452 "\tcalls: %u allocs, %u deallocs\n",
1453 name (), this, total_bytes (), allocated_bytes (),
1456 deallocations ());
1457#endif /* defined(TRACE) */
1458 }
1459
1460 // ======================================================================
1461
1462 inline bool
1464 memory_resource const& rhs) noexcept
1465 {
1466 return &lhs == &rhs || lhs.is_equal (rhs);
1467 }
1468
1469 inline bool
1471 memory_resource const& rhs) noexcept
1472 {
1473 return !(lhs == rhs);
1474 }
1475
1476 // ======================================================================
1477
1478 template <typename T>
1479 template <typename U>
1482 allocator_stateless_default_resource<U> const& other
1483 __attribute__ ((unused))) noexcept
1484 {
1485 }
1486
1487 template <typename T>
1490 {
1491 scheduler::critical_section scs;
1492
1493 return static_cast<value_type*> (get_default_resource ()->allocate (
1494 elements * sizeof (value_type)));
1495 }
1496
1497 template <typename T>
1498 inline void
1500 value_type* addr, std::size_t elements) noexcept
1501 {
1502 scheduler::critical_section scs;
1503
1505 elements * sizeof (value_type));
1506 }
1507
1508 template <typename T>
1509 inline std::size_t
1511 {
1512 return get_default_resource ()->max_size () / sizeof (value_type);
1513 }
1514
1515 // ======================================================================
1516
1517 template <typename T, typename U, typename L, F get_resource>
1518 inline bool
1519 operator== (allocator_stateless_polymorphic_synchronized<
1520 T, L, get_resource> const& lhs,
1521 allocator_stateless_polymorphic_synchronized<
1522 U, L, get_resource> const& rhs) noexcept
1523 {
1524 return *lhs.resource () == *rhs.resource ();
1525 }
1526
1527 template <typename T, typename U, typename L, F get_resource>
1528 inline bool
1529 operator!= (allocator_stateless_polymorphic_synchronized<
1530 T, L, get_resource> const& lhs,
1531 allocator_stateless_polymorphic_synchronized<
1532 U, L, get_resource> const& rhs) noexcept
1533 {
1534 return !(lhs == rhs);
1535 }
1536
1537 // ======================================================================
1538
1539 template <typename T, typename L, F get_resource>
1542 {
1543 trace::printf ("%s() @%p %p\n", __func__, this, get_resource ());
1544 }
1545
1546 template <typename T, typename L, F get_resource>
1547 template <typename U>
1550 allocator_stateless_polymorphic_synchronized<
1551 U, L, get_resource> const& other
1552 __attribute__ ((unused))) noexcept
1553 {
1554 }
1555
1556 template <typename T, typename L, F get_resource>
1557 typename allocator_stateless_polymorphic_synchronized<
1558 T, L, get_resource>::value_type*
1559 allocator_stateless_polymorphic_synchronized<
1560 T, L, get_resource>::allocate (std::size_t elements)
1561 {
1562 trace::printf ("%s(%u) @%p\n", __func__, elements, this);
1563
1564#if 0
1565 std::size_t ms = max_size ();
1566 if ((ms > 0) && (elements > max_size ()))
1567 {
1569 EINVAL,
1570 "allocator_stateless_polymorphic_synchronized<T>::allocate(size_t n)"
1571 " 'n' exceeds maximum supported size");
1572 }
1573#endif
1574
1575 locker_type lk;
1576 std::lock_guard<locker_type> ulk{ lk };
1577
1578 return static_cast<value_type*> (get_resource ()->allocate (
1579 elements * sizeof (value_type), alignof (value_type)));
1580 }
1581
1582 template <typename T, typename L, F get_resource>
1583 void
1584 allocator_stateless_polymorphic_synchronized<
1585 T, L, get_resource>::deallocate (value_type* addr,
1586 std::size_t elements) noexcept
1587 {
1588 trace::printf ("%s(%p,%u) @%p\n", __func__, addr, elements, this);
1589
1590#if 0
1591 std::size_t ms = max_size ();
1592 if (ms > 0)
1593 {
1594 assert (elements <= max_size ());
1595 }
1596#endif
1597
1598 locker_type lk;
1599 std::lock_guard<locker_type> ulk{ lk };
1600
1601 get_resource ()->deallocate (addr, elements * sizeof (value_type),
1602 alignof (value_type));
1603 }
1604
1605 template <typename T, typename L, F get_resource>
1606 inline std::size_t
1607 allocator_stateless_polymorphic_synchronized<
1608 T, L, get_resource>::max_size (void) const noexcept
1609 {
1610 return get_resource ()->max_size () / sizeof (T);
1611 }
1612
1613#if 0
1614 template<typename T, typename L, F get_resource>
1615 inline allocator_stateless_polymorphic_synchronized<T, L, get_resource>
1616 allocator_stateless_polymorphic_synchronized<T, L, get_resource>::select_on_container_copy_construction (
1617 void) const noexcept
1618 {
1619 return allocator_stateless_polymorphic_synchronized ();
1620 }
1621
1622 template<typename T, typename L, F get_resource>
1623 inline memory_resource*
1624 allocator_stateless_polymorphic_synchronized<T, L, get_resource>::resource (
1625 void) const noexcept
1626 {
1627 return get_resource ();
1628 }
1629#endif
1630
1631 // ======================================================================
1632
1633 template <typename A>
1635 {
1636 }
1637
1638 template <typename A>
1640 const allocator_type& other)
1641 : a_{ other }
1642 {
1643 }
1644
1652 template <typename A>
1653 inline void
1654 allocator_deleter<A>::operator() (pointer addr) const
1655 {
1656 // Local allocator, without it many errors are issued.
1657 // TODO: understand exactly why.
1658 allocator_type alloc{ a_ };
1659
1660 // Call the object destructor.
1661 allocator_traits::destroy (alloc, std::addressof (*addr));
1662
1663 // Deallocate the object, using the same allocator
1664 // used to allocate the object.
1665 allocator_traits::deallocate (alloc, addr, 1);
1666 }
1667
1668 // ======================================================================
1669
1681 template <typename T, typename A, typename... Args>
1682 auto
1683 allocate_unique (const A& allocator, Args&&... args)
1684 {
1688 using allocator_type = A;
1689
1693 using allocator_traits = std::allocator_traits<A>;
1694
1695 static_assert (
1696 std::is_same<typename allocator_traits::value_type,
1697 std::remove_cv_t<T>>::value
1698 || std::is_base_of<typename allocator_traits::value_type,
1699 std::remove_cv_t<T>>::value,
1700 "Allocator must be of same type or derived.");
1701
1702 static_assert (sizeof (T)
1703 <= sizeof (typename allocator_traits::value_type),
1704 "Derived type must not be larger.");
1705
1706 allocator_type alloc{ allocator };
1707
1708 // Allocate space for 1 object instance of type T.
1709 auto p = allocator_traits::allocate (alloc, 1);
1710
1711#if defined(__EXCEPTIONS)
1712
1713 try
1714 {
1715 // Use placement new to construct the object.
1716 allocator_traits::construct (alloc, std::addressof (*p),
1717 std::forward<Args> (args)...);
1718
1719 // Figure out the deleter type.
1720 using D = allocator_deleter<A>;
1721
1722 // Make the unique pointer with the object and the deleter.
1723 return std::unique_ptr<T, D> (p, D (alloc));
1724 }
1725 catch (...)
1726 {
1727 allocator_traits::deallocate (alloc, p, 1);
1728 throw;
1729 }
1730
1731#else
1732
1733 // Use placement new to construct the object.
1734 allocator_traits::construct (alloc, std::addressof (*p),
1735 std::forward<Args> (args)...);
1736
1737 // Figure out the deleter type.
1738 using D = allocator_deleter<A>;
1739
1740 // Make the unique pointer with the object and the deleter.
1741 return std::unique_ptr<T, D> (p, D (alloc));
1742
1743#endif /* defined(__EXCEPTIONS) */
1744 }
1745
1746 // ----------------------------------------------------------------------
1747 } /* namespace memory */
1748 } /* namespace rtos */
1749} /* namespace os */
1750
1751#pragma GCC diagnostic pop
1752
1753// ----------------------------------------------------------------------------
1754
1755#endif /* __cplusplus */
1756
1757// ----------------------------------------------------------------------------
1758
1759#endif /* CMSIS_PLUS_RTOS_OS_MEMORY_H_ */
Base class for named objects.
Definition os-decls.h:352
const char * name(void) const
Get object name.
Definition os-decls.h:753
allocator_deleter()
Default constructor.
A allocator_type
Standard allocator type definition.
Definition os-memory.h:856
allocator_deleter(allocator_deleter &&other)=default
Move constructor.
allocator_deleter(const allocator_type &other)
Copy constructor.
std::allocator_traits< A > allocator_traits
Standard allocator traits definition.
Definition os-memory.h:861
~allocator_deleter()=default
Destruct the allocator deleter.
typename allocator_traits::pointer pointer
Definition os-memory.h:863
Standard allocator based on the RTOS system default memory manager.
Definition os-memory.h:538
void deallocate(value_type *addr, std::size_t elements) noexcept
Deallocate the number of memory blocks of type value_type.
std::size_t max_size(void) const noexcept
The maximum number of elements that can be passed to allocate().
allocator_stateless_default_resource() noexcept=default
Default constructor. Construct a default resource allocator object instance.
value_type * allocate(std::size_t elements)
Allocate a number of memory blocks of type value_type.
T value_type
Type of elements to be allocated.
Definition os-memory.h:543
void deallocate(value_type *addr, std::size_t elements) noexcept
Deallocate the number of memory blocks of type value_type.
allocator_stateless_polymorphic_synchronized() noexcept
Default constructor. Construct a default allocator object instance.
std::size_t max_size(void) const noexcept
The maximum number of elements that can be passed to allocate().
value_type * allocate(std::size_t elements)
Allocate a number of memory blocks of type value_type.
Memory resource manager (abstract class).
Definition os-memory.h:159
bool is_equal(memory_resource const &other) const noexcept
Compare for equality with another memory_resource.
Definition os-memory.h:1331
virtual bool do_is_equal(memory_resource const &other) const noexcept
Implementation of the equality comparator.
virtual void do_reset(void) noexcept
Implementation of the function to reset the memory manager.
bool coalesce(void) noexcept
Coalesce free blocks.
Definition os-memory.h:1365
virtual void * do_allocate(std::size_t bytes, std::size_t alignment)=0
Implementation of the memory allocator.
virtual bool do_coalesce(void) noexcept
Implementation of the function to coalesce free blocks.
std::size_t max_size(void) const noexcept
Get the largest value that can be passed to allocate().
Definition os-memory.h:1340
virtual void do_deallocate(void *addr, std::size_t bytes, std::size_t alignment) noexcept=0
Implementation of the memory deallocator.
std::size_t allocated_chunks(void)
Get the current number of allocated chunks.
Definition os-memory.h:1420
memory_resource()=default
Default constructor. Construct a memory resource object instance.
void deallocate(void *addr, std::size_t bytes, std::size_t alignment=max_align) noexcept
Deallocate the previously allocated memory block.
Definition os-memory.h:1312
std::size_t allocated_bytes(void)
Get the current size of all allocated chunks.
Definition os-memory.h:1402
void internal_increase_allocated_statistics(std::size_t bytes) noexcept
Update statistics after allocation.
void * allocate(std::size_t bytes, std::size_t alignment=max_align)
Allocate a memory block.
Definition os-memory.h:1290
std::size_t max_allocated_bytes(void)
Get the maximum allocated size.
Definition os-memory.h:1408
out_of_memory_handler_t out_of_memory_handler(void)
Get the out of memory handler.
Definition os-memory.h:1390
std::size_t allocations(void)
Get the number of allocations.
Definition os-memory.h:1432
void reset(void) noexcept
Reset the memory manager to the initial state.
Definition os-memory.h:1349
void internal_decrease_allocated_statistics(std::size_t bytes) noexcept
Update statistics after deallocation.
std::size_t total_bytes(void)
Get the total size of managed memory.
Definition os-memory.h:1396
virtual std::size_t do_max_size(void) const noexcept
Implementation of the function to get max size.
void trace_print_statistics(void)
Print a long message with usage statistics.
Definition os-memory.h:1444
std::size_t deallocations(void)
Get the number of deallocations.
Definition os-memory.h:1438
std::size_t free_chunks(void)
Get the current number of free chunks.
Definition os-memory.h:1426
virtual ~memory_resource()
Destruct the memory resource object instance.
std::size_t free_bytes(void)
Get the current size of all free chunks.
Definition os-memory.h:1414
static constexpr std::size_t max_align
The largest alignment for the platform. Also default when supplied alignment is not supported.
Definition os-memory.h:166
Scheduler standard locker.
Definition os-sched.h:317
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
memory_resource * get_resource_typed< condition_variable >(void) noexcept
Definition os-memory.h:1166
memory_resource * get_resource_typed(void) noexcept
Function template to get a memory resource.
void init_once_default_resource(void)
memory_resource * set_default_resource(memory_resource *res) noexcept
Set the default RTOS system memory manager.
memory_resource * malloc_resource(void) noexcept
Get the address of a memory manager based on POSIX malloc().
memory_resource * get_resource_typed< thread >(void) noexcept
Definition os-memory.h:1151
bool operator==(const memory_resource &lhs, const memory_resource &rhs) noexcept
Compare the memory_resource instances for equality.
Definition os-memory.h:1463
std::unique_ptr< T, allocator_deleter< allocator_typed< T, U > > > unique_ptr
Type of a RTOS unique pointer to objects of type T.
Definition os-memory.h:1087
memory_resource * set_resource_typed< condition_variable >(memory_resource *res) noexcept
memory_resource * set_resource_typed(memory_resource *res) noexcept
Function template to set a memory resource.
memory_resource * set_resource_typed< message_queue >(memory_resource *res) noexcept
void(*)(void) out_of_memory_handler_t
Type of out of memory handler.
Definition os-memory.h:141
memory_resource * get_default_resource(void) noexcept
Get the default RTOS system memory manager.
Definition os-memory.h:1136
memory_resource * set_resource_typed< memory_pool >(memory_resource *res) noexcept
memory_resource * get_resource_typed< semaphore >(void) noexcept
Definition os-memory.h:1241
memory_resource * set_resource_typed< event_flags >(memory_resource *res) noexcept
bool operator!=(const memory_resource &lhs, const memory_resource &rhs) noexcept
Compare the memory_resource instances for inequality.
Definition os-memory.h:1470
memory_resource * get_resource_typed< timer >(void) noexcept
Definition os-memory.h:1256
memory_resource * set_resource_typed< mutex >(memory_resource *res) noexcept
auto allocate_unique(const A &allocator, Args &&... args)
Function template to allocate a unique pointer.
memory_resource * set_resource_typed< semaphore >(memory_resource *res) noexcept
allocator_stateless_default_resource< T > allocator
Type of allocator used by the system objects. Must be stateless.
Definition os-types.h:53
memory_resource * set_resource_typed< thread >(memory_resource *res) noexcept
memory_resource * get_resource_typed< message_queue >(void) noexcept
Definition os-memory.h:1211
memory_resource * get_resource_typed< memory_pool >(void) noexcept
Definition os-memory.h:1196
memory_resource * get_resource_typed< mutex >(void) noexcept
Definition os-memory.h:1226
memory_resource * get_resource_typed< event_flags >(void) noexcept
Definition os-memory.h:1181
memory_resource * set_resource_typed< timer >(memory_resource *res) noexcept
rtos::memory::memory_resource memory_resource
void __throw_system_error(int ev, const char *what_arg)
void __throw_bad_alloc(void)
constexpr std::size_t align_size(std::size_t size, std::size_t align) noexcept
Helper function to align size values.
Definition os-memory.h:85
constexpr std::size_t max(std::size_t a, std::size_t b)
Definition os-memory.h:73
System namespace.
Standard std namespace.