µ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 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#ifndef CMSIS_PLUS_RTOS_OS_MEMORY_H_
29#define CMSIS_PLUS_RTOS_OS_MEMORY_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
38
39#include <limits>
40#include <new>
41#include <cerrno>
42#include <mutex>
43
44// ----------------------------------------------------------------------------
45
46// These definitions refer only to the RTOS allocators.
47// The application should use the similar ones from the
48// os::estd:: namespace.
49
50#pragma GCC diagnostic push
51
52#if defined(__clang__)
53#pragma clang diagnostic ignored "-Wc++98-compat"
54#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
55#endif
56
57// ----------------------------------------------------------------------------
58
59namespace os
60{
61 namespace estd
62 {
63 [[noreturn]] void
64 __throw_bad_alloc (void);
65
66 template<typename L>
68
69 }
70
71 namespace rtos
72 {
73 namespace scheduler
74 {
75 class critical_section;
76 }
77
78 class null_locker;
79
80 namespace memory
81 {
82 // ----------------------------------------------------------------------
83
84 constexpr std::size_t
85 max (std::size_t a, std::size_t b)
86 {
87 return (a >= b) ? a : b;
88 }
89
96 constexpr std::size_t
97 align_size (std::size_t size, std::size_t align) noexcept
98 {
99 return ((size) + (align) - 1L) & ~((align) - 1L);
100 }
101
102 class memory_resource;
103
104 // ----------------------------------------------------------------------
105
122 memory_resource*
123 malloc_resource (void) noexcept;
124
130 memory_resource*
131 set_default_resource (memory_resource* res) noexcept;
132
139 memory_resource*
140 get_default_resource (void) noexcept;
141
142 void
144
149 // ======================================================================
153 using out_of_memory_handler_t = void (*)(void);
154
165 {
166
167 public:
168
173 static constexpr std::size_t max_align = alignof(std::max_align_t);
174
184 memory_resource () = default;
185
190 memory_resource (const char* name);
191
196 // The rule of five.
197 memory_resource (const memory_resource&) = delete;
198 memory_resource (memory_resource&&) = delete;
200 operator= (const memory_resource&) = delete;
202 operator= (memory_resource&&) = delete;
203
211 virtual
213
218 public:
219
231 void*
232 allocate (std::size_t bytes, std::size_t alignment = max_align);
233
242 void
243 deallocate (void* addr, std::size_t bytes, std::size_t alignment =
244 max_align) noexcept;
245
252 bool
253 is_equal (memory_resource const & other) const noexcept;
254
262 void
263 reset (void) noexcept;
264
272 bool
273 coalesce (void) noexcept;
274
281 std::size_t
282 max_size (void) const noexcept;
283
291
300
305 std::size_t
306 total_bytes (void);
307
314 std::size_t
315 allocated_bytes (void);
316
323 std::size_t
324 max_allocated_bytes (void);
325
332 std::size_t
333 free_bytes (void);
334
341 std::size_t
342 allocated_chunks (void);
343
350 std::size_t
351 free_chunks (void);
352
359 std::size_t
360 allocations (void);
361
368 std::size_t
369 deallocations (void);
370
378 void
380
385 protected:
386
398 virtual void*
399 do_allocate (std::size_t bytes, std::size_t alignment) = 0;
400
409 virtual void
410 do_deallocate (void* addr, std::size_t bytes, std::size_t alignment)
411 noexcept = 0;
412
419 virtual bool
420 do_is_equal (memory_resource const &other) const noexcept;
421
428 virtual std::size_t
429 do_max_size (void) const noexcept;
430
438 virtual void
439 do_reset (void) noexcept;
440
448 virtual bool
449 do_coalesce (void) noexcept;
450
457 void
458 internal_increase_allocated_statistics (std::size_t bytes) noexcept;
459
466 void
467 internal_decrease_allocated_statistics (std::size_t bytes) noexcept;
468
473 protected:
474
479 out_of_memory_handler_t out_of_memory_handler_ = nullptr;
480
481 std::size_t total_bytes_ = 0;
482 std::size_t allocated_bytes_ = 0;
483 std::size_t free_bytes_ = 0;
484 std::size_t allocated_chunks_ = 0;
485 std::size_t free_chunks_ = 0;
486 std::size_t max_allocated_bytes_ = 0;
487 std::size_t allocations_ = 0;
488 std::size_t deallocations_ = 0;
489
494 };
495
508 bool
509 operator== (const memory_resource& lhs, const memory_resource& rhs)
510 noexcept;
511
519 bool
520 operator!= (const memory_resource& lhs, const memory_resource& rhs)
521 noexcept;
522
527 // ======================================================================
542 template<typename T>
544 {
545 public:
546
550 using value_type = T;
551
562
568 allocator_stateless_default_resource const & other) = default;
569
574 template<typename U>
576 allocator_stateless_default_resource<U> const & other) noexcept;
577
583 allocator_stateless_default_resource && other) = default;
584
589
605 operator= (allocator_stateless_default_resource const & other) = default;
606
613 operator= (allocator_stateless_default_resource && other) = default;
614
619 public:
620
632 allocate (std::size_t elements);
633
641 void
642 deallocate (value_type* addr, std::size_t elements) noexcept;
643
649 std::size_t
650 max_size (void) const noexcept;
651
656 protected:
657
658 // This class should have no member variables, to meet the
659 // default allocator stateless requirements.
660 };
661
662 // ======================================================================
663
668 template<typename L>
669 class lock_guard;
670
671 using F = memory_resource* (void);
672
684 template<typename T, typename L, F get_resource>
686 {
687 public:
688
689 using value_type = T;
690 using locker_type = L;
691
702
708 allocator_stateless_polymorphic_synchronized const & other) = default;
709
714 template<typename U>
716 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & other)
717 noexcept;
718
725
730
746 operator= (allocator_stateless_polymorphic_synchronized const & other) = default;
747
754 operator= (allocator_stateless_polymorphic_synchronized && other) = default;
755
760 public:
761
776 template<typename U>
777 struct rebind
778 {
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
822 // This class should have no member variables, to meet the
823 // default allocator stateless requirements.
824 };
825
826 template<typename T1, typename T2, typename L, F get_resource>
827 bool
830 get_resource>& lhs,
832 get_resource>& rhs) noexcept;
833
834 template<typename T1, typename T2, typename L, F get_resource>
835 bool
838 get_resource>& lhs,
840 get_resource>& rhs) noexcept;
841
852 template<typename A>
854 {
855 public:
856
860 using allocator_type = A;
861
865 using allocator_traits = std::allocator_traits<A>;
866
867 using pointer = typename allocator_traits::pointer;
868
878
884
890
894 ~allocator_deleter () = default;
895
911 operator= (const allocator_deleter& other) = default;
912
919 operator= (allocator_deleter&& other) = default;
920
921 // /**
922 // * @brief Function operator.
923 // * @param addr Pointer to memory to deallocate.
924 // */
925 void
926 operator() (pointer addr) const;
927
932 protected:
933
939
943 };
944
955 template<typename T, typename A, typename ... Args>
956 auto
957 allocate_unique (const A& allocator, Args&&... args);
958
959 // ----------------------------------------------------------------------
960
971 template<typename T>
974
979 template<typename T>
981 get_resource_typed (void) noexcept;
982
983 // ----------------------------------------------------------------------
984
985 template<>
988
989 template<>
991 get_resource_typed<thread> (void) noexcept;
992
993 // ----------------------------------------------------------------------
994
995 template<>
998
999 template<>
1002
1003 // ----------------------------------------------------------------------
1004
1005 template<>
1008
1009 template<>
1011 get_resource_typed<event_flags> (void) noexcept;
1012
1013 // ----------------------------------------------------------------------
1014
1015 template<>
1018
1019 template<>
1021 get_resource_typed<memory_pool> (void) noexcept;
1022
1023 // ----------------------------------------------------------------------
1024
1025 template<>
1028
1029 template<>
1031 get_resource_typed<message_queue> (void) noexcept;
1032
1033 // ----------------------------------------------------------------------
1034
1035 template<>
1038
1039 template<>
1041 get_resource_typed<mutex> (void) noexcept;
1042
1043 // ----------------------------------------------------------------------
1044
1045 template<>
1048
1049 template<>
1051 get_resource_typed<semaphore> (void) noexcept;
1052
1053 // ----------------------------------------------------------------------
1054
1055 template<>
1058
1059 template<>
1061 get_resource_typed<timer> (void) noexcept;
1062
1067 // ----------------------------------------------------------------------
1076 template<typename T, typename U = T>
1078
1087 template<typename T, typename U = T>
1088 using unique_ptr = std::unique_ptr<T, allocator_deleter<allocator_typed<T, U>>>;
1089
1094 // ------------------------------------------------------------------------
1095 } /* namespace memory */
1096 } /* namespace rtos */
1097} /* namespace os */
1098
1099// ===== Inline & template implementations ====================================
1100
1101namespace os
1102{
1103 namespace rtos
1104 {
1105 namespace memory
1106 {
1107 // ----------------------------------------------------------------------
1108
1113 extern memory_resource* default_resource;
1114
1115 extern memory_resource* resource_thread;
1116 extern memory_resource* resource_condition_variable;
1117 extern memory_resource* resource_event_flags;
1118 extern memory_resource* resource_memory_pool;
1119 extern memory_resource* resource_message_queue;
1120 extern memory_resource* resource_mutex;
1121 extern memory_resource* resource_semaphore;
1122 extern memory_resource* resource_timer;
1123
1128 // ----------------------------------------------------------------------
1136 inline memory_resource*
1137 get_default_resource (void) noexcept
1138 {
1140 return default_resource;
1141 }
1142
1150 template<>
1152 get_resource_typed<thread> (void) noexcept
1153 {
1155 return resource_thread;
1156 }
1157
1165 template<>
1168 {
1170 return resource_condition_variable;
1171 }
1172
1180 template<>
1182 get_resource_typed<event_flags> (void) noexcept
1183 {
1185 return resource_event_flags;
1186 }
1187
1195 template<>
1197 get_resource_typed<memory_pool> (void) noexcept
1198 {
1200 return resource_memory_pool;
1201 }
1202
1210 template<>
1212 get_resource_typed<message_queue> (void) noexcept
1213 {
1215 return resource_message_queue;
1216 }
1217
1225 template<>
1227 get_resource_typed<mutex> (void) noexcept
1228 {
1230 return resource_mutex;
1231 }
1232
1240 template<>
1242 get_resource_typed<semaphore> (void) noexcept
1243 {
1245 return resource_semaphore;
1246 }
1247
1255 template<>
1257 get_resource_typed<timer> (void) noexcept
1258 {
1260 return resource_timer;
1261 }
1262
1263 // ======================================================================
1264
1265 inline
1267 object_named
1268 { name }
1269 {
1270 ;
1271 }
1272
1293 inline void*
1294 memory_resource::allocate (std::size_t bytes, std::size_t alignment)
1295 {
1296 ++allocations_;
1297 return do_allocate (bytes, alignment);
1298 }
1299
1315 inline void
1316 memory_resource::deallocate (void* addr, std::size_t bytes,
1317 std::size_t alignment) noexcept
1318 {
1319 ++deallocations_;
1320 do_deallocate (addr, bytes, alignment);
1321 }
1322
1334 inline bool
1335 memory_resource::is_equal (memory_resource const & other) const noexcept
1336 {
1337 return do_is_equal (other);
1338 }
1339
1343 inline std::size_t
1344 memory_resource::max_size (void) const noexcept
1345 {
1346 return do_max_size ();
1347 }
1348
1352 inline void
1354 {
1355 do_reset ();
1356 }
1357
1368 inline bool
1370 {
1371 return do_coalesce ();
1372 }
1373
1380 {
1381 trace::printf ("%s(%p) @%p %s\n", __func__, handler, this, name ());
1382
1383 out_of_memory_handler_t tmp = out_of_memory_handler_;
1384 out_of_memory_handler_ = handler;
1385
1386 return tmp;
1387 }
1388
1395 {
1396 return out_of_memory_handler_;
1397 }
1398
1399 inline std::size_t
1401 {
1402 return total_bytes_;
1403 }
1404
1405 inline std::size_t
1407 {
1408 return allocated_bytes_;
1409 }
1410
1411 inline std::size_t
1413 {
1414 return max_allocated_bytes_;
1415 }
1416
1417 inline std::size_t
1419 {
1420 return free_bytes_;
1421 }
1422
1423 inline std::size_t
1425 {
1426 return allocated_chunks_;
1427 }
1428
1429 inline std::size_t
1431 {
1432 return free_chunks_;
1433 }
1434
1435 inline std::size_t
1437 {
1438 return allocations_;
1439 }
1440
1441 inline std::size_t
1443 {
1444 return deallocations_;
1445 }
1446
1447 inline void
1449 {
1450#if defined(TRACE)
1451 trace::printf ("Memory '%s' @%p: \n"
1452 "\ttotal: %u bytes, \n"
1453 "\tallocated: %u bytes in %u chunk(s), \n"
1454 "\tfree: %u bytes in %u chunk(s), \n"
1455 "\tmax: %u bytes, \n"
1456 "\tcalls: %u allocs, %u deallocs\n",
1457 name (), this, total_bytes (), allocated_bytes (),
1460 deallocations ());
1461#endif /* defined(TRACE) */
1462 }
1463
1464 // ======================================================================
1465
1466 inline bool
1467 operator== (memory_resource const & lhs, memory_resource const & rhs) noexcept
1468 {
1469 return &lhs == &rhs || lhs.is_equal (rhs);
1470 }
1471
1472 inline bool
1473 operator!= (memory_resource const & lhs, memory_resource const & rhs) noexcept
1474 {
1475 return !(lhs == rhs);
1476 }
1477
1478 // ======================================================================
1479
1480 template<typename T>
1481 template<typename U>
1482 inline
1484 allocator_stateless_default_resource<U> const & other __attribute__((unused))) noexcept
1485 {
1486 ;
1487 }
1488
1489 template<typename T>
1492 {
1493 scheduler::critical_section scs;
1494
1495 return static_cast<value_type*> (get_default_resource ()->allocate (
1496 elements * sizeof(value_type)));
1497 }
1498
1499 template<typename T>
1500 inline void
1502 value_type* addr, std::size_t elements) noexcept
1503 {
1504 scheduler::critical_section scs;
1505
1507 elements * sizeof(value_type));
1508 }
1509
1510 template<typename T>
1511 inline std::size_t
1513 {
1514 return get_default_resource ()->max_size () / sizeof(value_type);
1515 }
1516
1517 // ======================================================================
1518
1519 template<typename T, typename U, typename L, F get_resource>
1520 inline bool
1522 allocator_stateless_polymorphic_synchronized<T, L, get_resource> const & lhs,
1523 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & rhs) noexcept
1524 {
1525 return *lhs.resource () == *rhs.resource ();
1526 }
1527
1528 template<typename T, typename U, typename L, F get_resource>
1529 inline bool
1531 allocator_stateless_polymorphic_synchronized<T, L, get_resource> const & lhs,
1532 allocator_stateless_polymorphic_synchronized<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>
1540 inline
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>
1548 inline
1550 allocator_stateless_polymorphic_synchronized<U, L, get_resource> const & other __attribute__((unused))) noexcept
1551 {
1552 ;
1553 }
1554
1555 template<typename T, typename L, F get_resource>
1558 std::size_t elements)
1559 {
1560 trace::printf ("%s(%u) @%p\n", __func__, elements, this);
1561
1562#if 0
1563 std::size_t ms = max_size ();
1564 if ((ms > 0) && (elements > max_size ()))
1565 {
1567 EINVAL,
1568 "allocator_stateless_polymorphic_synchronized<T>::allocate(size_t n)"
1569 " 'n' exceeds maximum supported size");
1570 }
1571#endif
1572
1573 locker_type lk;
1574 std::lock_guard<locker_type> ulk
1575 { lk };
1576
1577 return static_cast<value_type*> (get_resource ()->allocate (
1578 elements * sizeof(value_type), alignof(value_type)));
1579 }
1580
1581 template<typename T, typename L, F get_resource>
1582 void
1584 value_type* addr, std::size_t elements) noexcept
1585 {
1586 trace::printf ("%s(%p,%u) @%p\n", __func__, addr, elements, this);
1587
1588#if 0
1589 std::size_t ms = max_size ();
1590 if (ms > 0)
1591 {
1592 assert (elements <= max_size ());
1593 }
1594#endif
1595
1596 locker_type lk;
1597 std::lock_guard<locker_type> ulk
1598 { lk };
1599
1600 get_resource ()->deallocate (addr, elements * sizeof(value_type),
1601 alignof(value_type));
1602 }
1603
1604 template<typename T, typename L, F get_resource>
1605 inline std::size_t
1607 void) const noexcept
1608 {
1609 return get_resource ()->max_size () / sizeof(T);
1610 }
1611
1612#if 0
1613 template<typename T, typename L, F get_resource>
1614 inline allocator_stateless_polymorphic_synchronized<T, L, get_resource>
1615 allocator_stateless_polymorphic_synchronized<T, L, get_resource>::select_on_container_copy_construction (
1616 void) const noexcept
1617 {
1618 return allocator_stateless_polymorphic_synchronized ();
1619 }
1620
1621 template<typename T, typename L, F get_resource>
1622 inline memory_resource*
1623 allocator_stateless_polymorphic_synchronized<T, L, get_resource>::resource (
1624 void) const noexcept
1625 {
1626 return get_resource ();
1627 }
1628#endif
1629
1630 // ======================================================================
1631
1632 template<typename A>
1633 inline
1635 {
1636 ;
1637 }
1638
1639 template<typename A>
1640 inline
1641 allocator_deleter<A>::allocator_deleter (const allocator_type& other) :
1642 a_
1643 { other }
1644 {
1645 ;
1646 }
1647
1655 template<typename A>
1656 inline void
1657 allocator_deleter<A>::operator() (pointer addr) const
1658 {
1659 // Local allocator, without it many errors are issued.
1660 // TODO: understand exactly why.
1661 allocator_type alloc
1662 { a_ };
1663
1664 // Call the object destructor.
1665 allocator_traits::destroy (alloc, std::addressof (*addr));
1666
1667 // Deallocate the object, using the same allocator
1668 // used to allocate the object.
1669 allocator_traits::deallocate (alloc, addr, 1);
1670 }
1671
1672 // ======================================================================
1673
1685 template<typename T, typename A, typename ... Args>
1686 auto
1687 allocate_unique (const A& allocator, Args&&... args)
1688 {
1692 using allocator_type = A;
1693
1697 using allocator_traits = std::allocator_traits<A>;
1698
1699 static_assert(std::is_same<typename allocator_traits::value_type, std::remove_cv_t<T>>::value
1700 || std::is_base_of<typename allocator_traits::value_type, std::remove_cv_t<T>>::value,
1701 "Allocator must be of same type or derived.");
1702
1703 static_assert(sizeof(T) <= sizeof(typename allocator_traits::value_type),
1704 "Derived type must not be larger.");
1705
1706 allocator_type alloc
1707 { allocator };
1708
1709 // Allocate space for 1 object instance of type T.
1710 auto p = allocator_traits::allocate (alloc, 1);
1711
1712#if defined(__EXCEPTIONS)
1713
1714 try
1715 {
1716 // Use placement new to construct the object.
1717 allocator_traits::construct (alloc, std::addressof (*p),
1718 std::forward<Args>(args)...);
1719
1720 // Figure out the deleter type.
1721 using D = allocator_deleter<A>;
1722
1723 // Make the unique pointer with the object and the deleter.
1724 return std::unique_ptr<T, D> (p, D (alloc));
1725 }
1726 catch (...)
1727 {
1728 allocator_traits::deallocate (alloc, p, 1);
1729 throw;
1730 }
1731
1732#else
1733
1734 // Use placement new to construct the object.
1735 allocator_traits::construct (alloc, std::addressof (*p),
1736 std::forward<Args>(args)...);
1737
1738 // Figure out the deleter type.
1739 using D = allocator_deleter<A>;
1740
1741 // Make the unique pointer with the object and the deleter.
1742 return std::unique_ptr<T, D> (p, D (alloc));
1743
1744#endif /* defined(__EXCEPTIONS) */
1745 }
1746
1747 // ------------------------------------------------------------------------
1748 } /* namespace memory */
1749 } /* namespace rtos */
1750} /* namespace os */
1751
1752#pragma GCC diagnostic pop
1753
1754// ----------------------------------------------------------------------------
1755
1756#endif /* __cplusplus */
1757
1758// ----------------------------------------------------------------------------
1759
1760#endif /* CMSIS_PLUS_RTOS_OS_MEMORY_H_ */
Base class for named objects.
Definition os-decls.h:365
const char * name(void) const
Get object name.
Definition os-decls.h:774
allocator_deleter()
Default constructor.
A allocator_type
Standard allocator type definition.
Definition os-memory.h:860
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:865
~allocator_deleter()=default
Destruct the allocator deleter.
typename allocator_traits::pointer pointer
Definition os-memory.h:867
Standard allocator based on the RTOS system default memory manager.
Definition os-memory.h:544
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:550
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:165
bool is_equal(memory_resource const &other) const noexcept
Compare for equality with another memory_resource.
Definition os-memory.h:1335
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:1369
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:1344
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:1424
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:1316
std::size_t allocated_bytes(void)
Get the current size of all allocated chunks.
Definition os-memory.h:1406
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:1294
std::size_t max_allocated_bytes(void)
Get the maximum allocated size.
Definition os-memory.h:1412
out_of_memory_handler_t out_of_memory_handler(void)
Get the out of memory handler.
Definition os-memory.h:1394
std::size_t allocations(void)
Get the number of allocations.
Definition os-memory.h:1436
void reset(void) noexcept
Reset the memory manager to the initial state.
Definition os-memory.h:1353
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:1400
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:1448
std::size_t deallocations(void)
Get the number of deallocations.
Definition os-memory.h:1442
std::size_t free_chunks(void)
Get the current number of free chunks.
Definition os-memory.h:1430
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:1418
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:173
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
memory_resource * get_resource_typed< condition_variable >(void) noexcept
Definition os-memory.h:1167
void(*)(void) out_of_memory_handler_t
Type of out of memory handler.
Definition os-memory.h:153
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:1152
bool operator==(const memory_resource &lhs, const memory_resource &rhs) noexcept
Compare the memory_resource instances for equality.
Definition os-memory.h:1467
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:1088
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:1137
memory_resource * set_resource_typed< memory_pool >(memory_resource *res) noexcept
memory_resource * get_resource_typed< semaphore >(void) noexcept
Definition os-memory.h:1242
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:1473
memory_resource * get_resource_typed< timer >(void) noexcept
Definition os-memory.h:1257
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:67
memory_resource * set_resource_typed< thread >(memory_resource *res) noexcept
memory_resource * get_resource_typed< message_queue >(void) noexcept
Definition os-memory.h:1212
memory_resource * get_resource_typed< memory_pool >(void) noexcept
Definition os-memory.h:1197
memory_resource * get_resource_typed< mutex >(void) noexcept
Definition os-memory.h:1227
memory_resource * get_resource_typed< event_flags >(void) noexcept
Definition os-memory.h:1182
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:97
constexpr std::size_t max(std::size_t a, std::size_t b)
Definition os-memory.h:85
System namespace.
Standard std namespace.