µ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++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2016-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13#ifndef CMSIS_PLUS_RTOS_OS_MEMORY_H_
14#define CMSIS_PLUS_RTOS_OS_MEMORY_H_
15
16// ----------------------------------------------------------------------------
17
18#if defined(__cplusplus)
19
20// ----------------------------------------------------------------------------
21
23
24#include <limits>
25#include <new>
26#include <cerrno>
27#include <mutex>
28
29// ----------------------------------------------------------------------------
30
31// These definitions refer only to the RTOS allocators.
32// The application should use the similar ones from the
33// os::estd:: namespace.
34
35#pragma GCC diagnostic push
36#if defined(__clang__)
37#pragma clang diagnostic ignored "-Wc++98-compat"
38#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
39#endif
40
41// ----------------------------------------------------------------------------
42
43namespace os
44{
45 namespace estd
46 {
47#pragma GCC diagnostic push
48#if defined(__clang__)
49#pragma clang diagnostic ignored "-Wreserved-identifier"
50#endif
51 [[noreturn]] void
52 __throw_bad_alloc (void);
53#pragma GCC diagnostic pop
54
55 template<typename L>
57
58 }
59
60 namespace rtos
61 {
62 namespace scheduler
63 {
64 class critical_section;
65 }
66
67 class null_locker;
68
69 namespace memory
70 {
71 // ----------------------------------------------------------------------
72
73 constexpr std::size_t
74 max (std::size_t a, std::size_t b)
75 {
76 return (a >= b) ? a : b;
77 }
78
85 constexpr std::size_t
86 align_size (std::size_t size, std::size_t align) noexcept
87 {
88 return ((size) + (align) - 1L) & ~((align) - 1L);
89 }
90
91 class memory_resource;
92
93 // ----------------------------------------------------------------------
94
111 memory_resource*
112 malloc_resource (void) noexcept;
113
119 memory_resource*
120 set_default_resource (memory_resource* res) noexcept;
121
128 memory_resource*
129 get_default_resource (void) noexcept;
130
131 void
133
138 // ======================================================================
142 using out_of_memory_handler_t = void (*)(void);
143
153#pragma GCC diagnostic push
154#if defined(__clang__)
155#elif defined(__GNUC__)
156#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
157#pragma GCC diagnostic ignored "-Wsuggest-final-types"
158#endif
160 {
161
162 public:
163
168 static constexpr std::size_t max_align = alignof(std::max_align_t);
169
179 memory_resource () = default;
180
185 memory_resource (const char* name);
186
191 // The rule of five.
192 memory_resource (const memory_resource&) = delete;
193 memory_resource (memory_resource&&) = delete;
195 operator= (const memory_resource&) = delete;
197 operator= (memory_resource&&) = delete;
198
206 virtual
208
213 public:
214
226 void*
227 allocate (std::size_t bytes, std::size_t alignment = max_align);
228
237 void
238 deallocate (void* addr, std::size_t bytes, std::size_t alignment =
239 max_align) noexcept;
240
247 bool
248 is_equal (memory_resource const & other) const noexcept;
249
257 void
258 reset (void) noexcept;
259
267 bool
268 coalesce (void) noexcept;
269
276 std::size_t
277 max_size (void) const noexcept;
278
286
295
300 std::size_t
301 total_bytes (void);
302
309 std::size_t
310 allocated_bytes (void);
311
318 std::size_t
319 max_allocated_bytes (void);
320
327 std::size_t
328 free_bytes (void);
329
336 std::size_t
337 allocated_chunks (void);
338
345 std::size_t
346 free_chunks (void);
347
354 std::size_t
355 allocations (void);
356
363 std::size_t
364 deallocations (void);
365
373 void
375
380 protected:
381
393 virtual void*
394 do_allocate (std::size_t bytes, std::size_t alignment) = 0;
395
404 virtual void
405 do_deallocate (void* addr, std::size_t bytes, std::size_t alignment)
406 noexcept = 0;
407
414 virtual bool
415 do_is_equal (memory_resource const &other) const noexcept;
416
423 virtual std::size_t
424 do_max_size (void) const noexcept;
425
433 virtual void
434 do_reset (void) noexcept;
435
443 virtual bool
444 do_coalesce (void) noexcept;
445
452 void
453 internal_increase_allocated_statistics (std::size_t bytes) noexcept;
454
461 void
462 internal_decrease_allocated_statistics (std::size_t bytes) noexcept;
463
468 protected:
469
474 out_of_memory_handler_t out_of_memory_handler_ = nullptr;
475
476 std::size_t total_bytes_ = 0;
477 std::size_t allocated_bytes_ = 0;
478 std::size_t free_bytes_ = 0;
479 std::size_t allocated_chunks_ = 0;
480 std::size_t free_chunks_ = 0;
481 std::size_t max_allocated_bytes_ = 0;
482 std::size_t allocations_ = 0;
483 std::size_t deallocations_ = 0;
484
489 };
490#pragma GCC diagnostic pop
491
504 bool
505 operator== (const memory_resource& lhs, const memory_resource& rhs)
506 noexcept;
507
515 bool
516 operator!= (const memory_resource& lhs, const memory_resource& rhs)
517 noexcept;
518
523 // ======================================================================
538 template<typename T>
540 {
541 public:
542
546 using value_type = T;
547
558
564 allocator_stateless_default_resource const & other) = default;
565
570 template<typename U>
572 allocator_stateless_default_resource<U> const & other) noexcept;
573
579 allocator_stateless_default_resource && other) = default;
580
585
601 operator= (allocator_stateless_default_resource const & other) = default;
602
609 operator= (allocator_stateless_default_resource && other) = default;
610
615 public:
616
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
654 // This class should have no member variables, to meet the
655 // default allocator stateless requirements.
656 };
657
658 // ======================================================================
659
664 template<typename L>
665 class lock_guard;
666
667 using F = memory_resource* (void);
668
680 template<typename T, typename L, F get_resource>
682 {
683 public:
684
685 using value_type = T;
686 using locker_type = L;
687
698
704 allocator_stateless_polymorphic_synchronized const & other) = default;
705
710 template<typename U>
712 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & other)
713 noexcept;
714
721
726
742 operator= (allocator_stateless_polymorphic_synchronized const & other) = default;
743
750 operator= (allocator_stateless_polymorphic_synchronized && other) = default;
751
756 public:
757
772 template<typename U>
773 struct rebind
774 {
776 };
777
784 allocate (std::size_t elements);
785
793 void
794 deallocate (value_type* addr, std::size_t elements) noexcept;
795
801 std::size_t
802 max_size (void) const noexcept;
803
804#if 0
806 select_on_container_copy_construction (void) const noexcept;
807
809 resource (void) const noexcept;
810#endif
811
816 private:
817
818 // This class should have no member variables, to meet the
819 // default allocator stateless requirements.
820 };
821
822 template<typename T1, typename T2, typename L, F get_resource>
823 bool
826 get_resource>& lhs,
828 get_resource>& rhs) noexcept;
829
830 template<typename T1, typename T2, typename L, F get_resource>
831 bool
834 get_resource>& lhs,
836 get_resource>& rhs) noexcept;
837
848 template<typename A>
850 {
851 public:
852
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) = default;
908
915 operator= (allocator_deleter&& other) = default;
916
917 // /**
918 // * @brief Function operator.
919 // * @param addr Pointer to memory to deallocate.
920 // */
921 void
922 operator() (pointer addr) const;
923
928 protected:
929
935
939 };
940
951 template<typename T, typename A, typename ... Args>
952 auto
953 allocate_unique (const A& allocator, Args&&... args);
954
955 // ----------------------------------------------------------------------
956
967 template<typename T>
970
975 template<typename T>
977 get_resource_typed (void) noexcept;
978
979 // ----------------------------------------------------------------------
980
981 template<>
984
985 template<>
987 get_resource_typed<thread> (void) noexcept;
988
989 // ----------------------------------------------------------------------
990
991 template<>
994
995 template<>
998
999 // ----------------------------------------------------------------------
1000
1001 template<>
1004
1005 template<>
1007 get_resource_typed<event_flags> (void) noexcept;
1008
1009 // ----------------------------------------------------------------------
1010
1011 template<>
1014
1015 template<>
1017 get_resource_typed<memory_pool> (void) noexcept;
1018
1019 // ----------------------------------------------------------------------
1020
1021 template<>
1024
1025 template<>
1027 get_resource_typed<message_queue> (void) noexcept;
1028
1029 // ----------------------------------------------------------------------
1030
1031 template<>
1034
1035 template<>
1037 get_resource_typed<mutex> (void) noexcept;
1038
1039 // ----------------------------------------------------------------------
1040
1041 template<>
1044
1045 template<>
1047 get_resource_typed<semaphore> (void) noexcept;
1048
1049 // ----------------------------------------------------------------------
1050
1051 template<>
1054
1055 template<>
1057 get_resource_typed<timer> (void) noexcept;
1058
1063 // ----------------------------------------------------------------------
1072 template<typename T, typename U = T>
1074
1083 template<typename T, typename U = T>
1084 using unique_ptr = std::unique_ptr<T, allocator_deleter<allocator_typed<T, U>>>;
1085
1090 // ------------------------------------------------------------------------
1091 } /* namespace memory */
1092 } /* namespace rtos */
1093} /* namespace os */
1094
1095// ===== Inline & template implementations ====================================
1096
1097namespace os
1098{
1099 namespace rtos
1100 {
1101 namespace memory
1102 {
1103 // ----------------------------------------------------------------------
1104
1109 extern memory_resource* default_resource;
1110
1111 extern memory_resource* resource_thread;
1112 extern memory_resource* resource_condition_variable;
1113 extern memory_resource* resource_event_flags;
1114 extern memory_resource* resource_memory_pool;
1115 extern memory_resource* resource_message_queue;
1116 extern memory_resource* resource_mutex;
1117 extern memory_resource* resource_semaphore;
1118 extern memory_resource* resource_timer;
1119
1124 // ----------------------------------------------------------------------
1132 inline memory_resource*
1133 get_default_resource (void) noexcept
1134 {
1136 return default_resource;
1137 }
1138
1146 template<>
1148 get_resource_typed<thread> (void) noexcept
1149 {
1151 return resource_thread;
1152 }
1153
1161 template<>
1164 {
1166 return resource_condition_variable;
1167 }
1168
1176 template<>
1178 get_resource_typed<event_flags> (void) noexcept
1179 {
1181 return resource_event_flags;
1182 }
1183
1191 template<>
1193 get_resource_typed<memory_pool> (void) noexcept
1194 {
1196 return resource_memory_pool;
1197 }
1198
1206 template<>
1208 get_resource_typed<message_queue> (void) noexcept
1209 {
1211 return resource_message_queue;
1212 }
1213
1221 template<>
1223 get_resource_typed<mutex> (void) noexcept
1224 {
1226 return resource_mutex;
1227 }
1228
1236 template<>
1238 get_resource_typed<semaphore> (void) noexcept
1239 {
1241 return resource_semaphore;
1242 }
1243
1251 template<>
1253 get_resource_typed<timer> (void) noexcept
1254 {
1256 return resource_timer;
1257 }
1258
1259 // ======================================================================
1260
1261 inline
1263 object_named
1264 { name }
1265 {
1266 }
1267
1288 inline void*
1289 memory_resource::allocate (std::size_t bytes, std::size_t alignment)
1290 {
1291 ++allocations_;
1292 return do_allocate (bytes, alignment);
1293 }
1294
1310 inline void
1311 memory_resource::deallocate (void* addr, std::size_t bytes,
1312 std::size_t alignment) noexcept
1313 {
1314 ++deallocations_;
1315 do_deallocate (addr, bytes, alignment);
1316 }
1317
1329 inline bool
1330 memory_resource::is_equal (memory_resource const & other) const noexcept
1331 {
1332 return do_is_equal (other);
1333 }
1334
1338 inline std::size_t
1339 memory_resource::max_size (void) const noexcept
1340 {
1341 return do_max_size ();
1342 }
1343
1347 inline void
1349 {
1350 do_reset ();
1351 }
1352
1363 inline bool
1365 {
1366 return do_coalesce ();
1367 }
1368
1375 {
1376 trace::printf ("%s(%p) @%p %s\n", __func__, handler, this, name ());
1377
1378 out_of_memory_handler_t tmp = out_of_memory_handler_;
1379 out_of_memory_handler_ = handler;
1380
1381 return tmp;
1382 }
1383
1390 {
1391 return out_of_memory_handler_;
1392 }
1393
1394 inline std::size_t
1396 {
1397 return total_bytes_;
1398 }
1399
1400 inline std::size_t
1402 {
1403 return allocated_bytes_;
1404 }
1405
1406 inline std::size_t
1408 {
1409 return max_allocated_bytes_;
1410 }
1411
1412 inline std::size_t
1414 {
1415 return free_bytes_;
1416 }
1417
1418 inline std::size_t
1420 {
1421 return allocated_chunks_;
1422 }
1423
1424 inline std::size_t
1426 {
1427 return free_chunks_;
1428 }
1429
1430 inline std::size_t
1432 {
1433 return allocations_;
1434 }
1435
1436 inline std::size_t
1438 {
1439 return deallocations_;
1440 }
1441
1442 inline void
1444 {
1445#if defined(TRACE)
1446 trace::printf ("Memory '%s' @%p: \n"
1447 "\ttotal: %u bytes, \n"
1448 "\tallocated: %u bytes in %u chunk(s), \n"
1449 "\tfree: %u bytes in %u chunk(s), \n"
1450 "\tmax: %u bytes, \n"
1451 "\tcalls: %u allocs, %u deallocs\n",
1452 name (), this, total_bytes (), allocated_bytes (),
1455 deallocations ());
1456#endif /* defined(TRACE) */
1457 }
1458
1459 // ======================================================================
1460
1461 inline bool
1462 operator== (memory_resource const & lhs, memory_resource const & rhs) noexcept
1463 {
1464 return &lhs == &rhs || lhs.is_equal (rhs);
1465 }
1466
1467 inline bool
1468 operator!= (memory_resource const & lhs, memory_resource const & rhs) noexcept
1469 {
1470 return !(lhs == rhs);
1471 }
1472
1473 // ======================================================================
1474
1475 template<typename T>
1476 template<typename U>
1477 inline
1479 allocator_stateless_default_resource<U> const & other __attribute__((unused))) noexcept
1480 {
1481 }
1482
1483 template<typename T>
1486 {
1487 scheduler::critical_section scs;
1488
1489 return static_cast<value_type*> (get_default_resource ()->allocate (
1490 elements * sizeof(value_type)));
1491 }
1492
1493 template<typename T>
1494 inline void
1496 value_type* addr, std::size_t elements) noexcept
1497 {
1498 scheduler::critical_section scs;
1499
1501 elements * sizeof(value_type));
1502 }
1503
1504 template<typename T>
1505 inline std::size_t
1507 {
1508 return get_default_resource ()->max_size () / sizeof(value_type);
1509 }
1510
1511 // ======================================================================
1512
1513 template<typename T, typename U, typename L, F get_resource>
1514 inline bool
1516 allocator_stateless_polymorphic_synchronized<T, L, get_resource> const & lhs,
1517 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & rhs) noexcept
1518 {
1519 return *lhs.resource () == *rhs.resource ();
1520 }
1521
1522 template<typename T, typename U, typename L, F get_resource>
1523 inline bool
1525 allocator_stateless_polymorphic_synchronized<T, L, get_resource> const & lhs,
1526 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & rhs) noexcept
1527 {
1528 return !(lhs == rhs);
1529 }
1530
1531 // ======================================================================
1532
1533 template<typename T, typename L, F get_resource>
1534 inline
1536 {
1537 trace::printf ("%s() @%p %p\n", __func__, this, get_resource ());
1538 }
1539
1540 template<typename T, typename L, F get_resource>
1541 template<typename U>
1542 inline
1544 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & other __attribute__((unused))) noexcept
1545 {
1546 }
1547
1548 template<typename T, typename L, F get_resource>
1551 std::size_t elements)
1552 {
1553 trace::printf ("%s(%u) @%p\n", __func__, elements, this);
1554
1555#if 0
1556 std::size_t ms = max_size ();
1557 if ((ms > 0) && (elements > max_size ()))
1558 {
1560 EINVAL,
1561 "allocator_stateless_polymorphic_synchronized<T>::allocate(size_t n)"
1562 " 'n' exceeds maximum supported size");
1563 }
1564#endif
1565
1566 locker_type lk;
1567 std::lock_guard<locker_type> ulk
1568 { lk };
1569
1570 return static_cast<value_type*> (get_resource ()->allocate (
1571 elements * sizeof(value_type), alignof(value_type)));
1572 }
1573
1574 template<typename T, typename L, F get_resource>
1575 void
1577 value_type* addr, std::size_t elements) noexcept
1578 {
1579 trace::printf ("%s(%p,%u) @%p\n", __func__, addr, elements, this);
1580
1581#if 0
1582 std::size_t ms = max_size ();
1583 if (ms > 0)
1584 {
1585 assert (elements <= max_size ());
1586 }
1587#endif
1588
1589 locker_type lk;
1590 std::lock_guard<locker_type> ulk
1591 { lk };
1592
1593 get_resource ()->deallocate (addr, elements * sizeof(value_type),
1594 alignof(value_type));
1595 }
1596
1597 template<typename T, typename L, F get_resource>
1598 inline std::size_t
1600 void) const noexcept
1601 {
1602 return get_resource ()->max_size () / sizeof(T);
1603 }
1604
1605#if 0
1606 template<typename T, typename L, F get_resource>
1607 inline allocator_stateless_polymorphic_synchronized<T, L, get_resource>
1608 allocator_stateless_polymorphic_synchronized<T, L, get_resource>::select_on_container_copy_construction (
1609 void) const noexcept
1610 {
1611 return allocator_stateless_polymorphic_synchronized ();
1612 }
1613
1614 template<typename T, typename L, F get_resource>
1615 inline memory_resource*
1616 allocator_stateless_polymorphic_synchronized<T, L, get_resource>::resource (
1617 void) const noexcept
1618 {
1619 return get_resource ();
1620 }
1621#endif
1622
1623 // ======================================================================
1624
1625 template<typename A>
1626 inline
1628 {
1629 }
1630
1631 template<typename A>
1632 inline
1633 allocator_deleter<A>::allocator_deleter (const allocator_type& other) :
1634 a_
1635 { other }
1636 {
1637 }
1638
1646 template<typename A>
1647 inline void
1648 allocator_deleter<A>::operator() (pointer addr) const
1649 {
1650 // Local allocator, without it many errors are issued.
1651 // TODO: understand exactly why.
1652 allocator_type alloc
1653 { a_ };
1654
1655 // Call the object destructor.
1656 allocator_traits::destroy (alloc, std::addressof (*addr));
1657
1658 // Deallocate the object, using the same allocator
1659 // used to allocate the object.
1660 allocator_traits::deallocate (alloc, addr, 1);
1661 }
1662
1663 // ======================================================================
1664
1676 template<typename T, typename A, typename ... Args>
1677 auto
1678 allocate_unique (const A& allocator, Args&&... args)
1679 {
1683 using allocator_type = A;
1684
1688 using allocator_traits = std::allocator_traits<A>;
1689
1690 static_assert(std::is_same<typename allocator_traits::value_type, std::remove_cv_t<T>>::value
1691 || std::is_base_of<typename allocator_traits::value_type, std::remove_cv_t<T>>::value,
1692 "Allocator must be of same type or derived.");
1693
1694 static_assert(sizeof(T) <= sizeof(typename allocator_traits::value_type),
1695 "Derived type must not be larger.");
1696
1697 allocator_type alloc
1698 { allocator };
1699
1700 // Allocate space for 1 object instance of type T.
1701 auto p = allocator_traits::allocate (alloc, 1);
1702
1703#if defined(__EXCEPTIONS)
1704
1705 try
1706 {
1707 // Use placement new to construct the object.
1708 allocator_traits::construct (alloc, std::addressof (*p),
1709 std::forward<Args>(args)...);
1710
1711 // Figure out the deleter type.
1712 using D = allocator_deleter<A>;
1713
1714 // Make the unique pointer with the object and the deleter.
1715 return std::unique_ptr<T, D> (p, D (alloc));
1716 }
1717 catch (...)
1718 {
1719 allocator_traits::deallocate (alloc, p, 1);
1720 throw;
1721 }
1722
1723#else
1724
1725 // Use placement new to construct the object.
1726 allocator_traits::construct (alloc, std::addressof (*p),
1727 std::forward<Args>(args)...);
1728
1729 // Figure out the deleter type.
1730 using D = allocator_deleter<A>;
1731
1732 // Make the unique pointer with the object and the deleter.
1733 return std::unique_ptr<T, D> (p, D (alloc));
1734
1735#endif /* defined(__EXCEPTIONS) */
1736 }
1737
1738 // ------------------------------------------------------------------------
1739 } /* namespace memory */
1740 } /* namespace rtos */
1741} /* namespace os */
1742
1743#pragma GCC diagnostic pop
1744
1745// ----------------------------------------------------------------------------
1746
1747#endif /* __cplusplus */
1748
1749// ----------------------------------------------------------------------------
1750
1751#endif /* CMSIS_PLUS_RTOS_OS_MEMORY_H_ */
Base class for named objects.
Definition os-decls.h:351
const char * name(void) const
Get object name.
Definition os-decls.h:759
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:540
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:546
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:160
bool is_equal(memory_resource const &other) const noexcept
Compare for equality with another memory_resource.
Definition os-memory.h:1330
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:1364
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:1339
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:1419
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:1311
std::size_t allocated_bytes(void)
Get the current size of all allocated chunks.
Definition os-memory.h:1401
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:1289
std::size_t max_allocated_bytes(void)
Get the maximum allocated size.
Definition os-memory.h:1407
out_of_memory_handler_t out_of_memory_handler(void)
Get the out of memory handler.
Definition os-memory.h:1389
std::size_t allocations(void)
Get the number of allocations.
Definition os-memory.h:1431
void reset(void) noexcept
Reset the memory manager to the initial state.
Definition os-memory.h:1348
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:1395
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:1443
std::size_t deallocations(void)
Get the number of deallocations.
Definition os-memory.h:1437
std::size_t free_chunks(void)
Get the current number of free chunks.
Definition os-memory.h:1425
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:1413
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:168
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
memory_resource * get_resource_typed< condition_variable >(void) noexcept
Definition os-memory.h:1163
void(*)(void) out_of_memory_handler_t
Type of out of memory handler.
Definition os-memory.h:142
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:1148
bool operator==(const memory_resource &lhs, const memory_resource &rhs) noexcept
Compare the memory_resource instances for equality.
Definition os-memory.h:1462
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:1084
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
memory_resource * get_default_resource(void) noexcept
Get the default RTOS system memory manager.
Definition os-memory.h:1133
memory_resource * set_resource_typed< memory_pool >(memory_resource *res) noexcept
memory_resource * get_resource_typed< semaphore >(void) noexcept
Definition os-memory.h:1238
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:1468
memory_resource * get_resource_typed< timer >(void) noexcept
Definition os-memory.h:1253
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:54
memory_resource * set_resource_typed< thread >(memory_resource *res) noexcept
memory_resource * get_resource_typed< message_queue >(void) noexcept
Definition os-memory.h:1208
memory_resource * get_resource_typed< memory_pool >(void) noexcept
Definition os-memory.h:1193
memory_resource * get_resource_typed< mutex >(void) noexcept
Definition os-memory.h:1223
memory_resource * get_resource_typed< event_flags >(void) noexcept
Definition os-memory.h:1178
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:86
constexpr std::size_t max(std::size_t a, std::size_t b)
Definition os-memory.h:74
System namespace.
Standard std namespace.