Skip to content

Commit afb6f13

Browse files
authored
Add convienence functions to MemoryAllocator (#4439)
* Add convienence functions to MemoryAllocator * Fix comments
1 parent 6388f04 commit afb6f13

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

Fw/Types/MemAllocator.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,27 @@ MemAllocator::MemAllocator() {}
1515

1616
MemAllocator::~MemAllocator() {}
1717

18+
void* MemAllocator::allocate(const FwEnumStoreType identifier, FwSizeType& size, FwSizeType alignment) {
19+
bool unused = false;
20+
return this->allocate(identifier, size, unused, alignment);
21+
}
22+
23+
void* MemAllocator ::checkedAllocate(const FwEnumStoreType identifier,
24+
FwSizeType& size,
25+
bool& recoverable,
26+
FwSizeType alignment) {
27+
FwSizeType requestedSize = size;
28+
void* memory = this->allocate(identifier, size, recoverable, alignment);
29+
FW_ASSERT(memory != nullptr && size >= requestedSize, static_cast<FwAssertArgType>(identifier),
30+
static_cast<FwAssertArgType>(requestedSize), static_cast<FwAssertArgType>(size));
31+
return memory;
32+
}
33+
34+
void* MemAllocator ::checkedAllocate(const FwEnumStoreType identifier, FwSizeType& size, FwSizeType alignment) {
35+
bool unused = false;
36+
return this->checkedAllocate(identifier, size, unused, alignment);
37+
}
38+
1839
MemAllocatorRegistry::MemAllocatorRegistry() {
1940
// Register self as the singleton
2041
MemAllocatorRegistry::s_registry = this;

Fw/Types/MemAllocator.hpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,54 @@ class MemAllocator {
7474
//! \param ptr the pointer to memory returned by allocate()
7575
virtual void deallocate(const FwEnumStoreType identifier, void* ptr) = 0;
7676

77+
//! Allocate memory without recoverable flag
78+
//!
79+
//! This is a convenience method that calls allocate() without the recoverable flag. The recoverable flag is filled
80+
//! by the underlying allocator but is not returned to the caller. This is for cases when the caller does not care
81+
//! about recoverability of memory.
82+
//!
83+
//! \param identifier the memory segment identifier, each identifier is to be used in once single allocation
84+
//! \param size the requested size - changed to actual if different
85+
//! \param alignment - alignment requirement for the allocation. Default: maximum alignment defined by C++.
86+
//! \return the pointer to memory. Zero if unable to allocate
87+
void* allocate(const FwEnumStoreType identifier,
88+
FwSizeType& size,
89+
FwSizeType alignment = alignof(std::max_align_t));
90+
91+
//! Allocate memory checking that the allocation was successful
92+
//!
93+
//! This is a convenience method that calls allocate() and checks that the returned pointer is not null and that
94+
//! size is at least as large as the requested size.
95+
//!
96+
//! Allocations are checked using FW_ASSERT implying that an allocation failure results in a tripped assertion.
97+
//!
98+
//! \param identifier the memory segment identifier, each identifier is to be used in once single allocation
99+
//! \param size the requested size, actual allocation will be at least this size
100+
//! \param recoverable - flag to indicate the memory could be recoverable
101+
//! \param alignment - alignment requirement for the allocation. Default: maximum alignment defined by C++.
102+
//! \return the pointer to memory. Zero if unable to allocate
103+
void* checkedAllocate(const FwEnumStoreType identifier,
104+
FwSizeType& size,
105+
bool& recoverable,
106+
FwSizeType alignment = alignof(std::max_align_t));
107+
108+
//! Allocate memory checking that the allocation was successful without recoverable flag
109+
//!
110+
//! This is a convenience method that calls allocate() and checks that the returned pointer is not null and that
111+
//! size is at least as large as the requested size. The recoverable flag is filled by the underlying allocator
112+
//! but is not returned to the caller. This is for cases when the caller does not care about recoverability of
113+
//! memory.
114+
//!
115+
//! Allocations are checked using FW_ASSERT implying that an allocation failure results in a tripped assertion.
116+
//!
117+
//! \param identifier the memory segment identifier, each identifier is to be used in once single allocation
118+
//! \param size the requested size, actual allocation will be at least this size
119+
//! \param alignment - alignment requirement for the allocation. Default: maximum alignment defined by C++.
120+
//! \return the pointer to memory. Zero if unable to allocate
121+
void* checkedAllocate(const FwEnumStoreType identifier,
122+
FwSizeType& size,
123+
FwSizeType alignment = alignof(std::max_align_t));
124+
77125
protected:
78126
MemAllocator();
79127
virtual ~MemAllocator();

Fw/Types/test/ut/TypesTest.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,62 @@ TEST(AllocatorTest, MallocAllocatorTest) {
15881588
allocator.deallocate(100, ptr);
15891589
}
15901590

1591+
TEST(AllocatorTest, MallocAllocatorTestNoRecoverable) {
1592+
// Since it is a wrapper around malloc, the test consists of requesting
1593+
// memory and verifying a non-zero pointer, unchanged size, and not recoverable.
1594+
Fw::MallocAllocator allocator;
1595+
Fw::MemAllocator& memAllocator = allocator;
1596+
FwSizeType size = 100; // one hundred bytes
1597+
void* ptr = memAllocator.allocate(10, size);
1598+
ASSERT_EQ(100, size);
1599+
ASSERT_NE(ptr, nullptr);
1600+
// deallocate memory
1601+
allocator.deallocate(100, ptr);
1602+
}
1603+
1604+
TEST(AllocatorTest, MallocCheckedAllocate) {
1605+
// Since it is a wrapper around malloc, the test consists of requesting
1606+
// memory and verifying a non-zero pointer, unchanged size, and not recoverable.
1607+
Fw::MallocAllocator allocator;
1608+
FwSizeType size = 100; // one hundred bytes
1609+
bool recoverable;
1610+
void* ptr = allocator.checkedAllocate(10, size, recoverable);
1611+
ASSERT_EQ(100, size);
1612+
ASSERT_NE(ptr, nullptr);
1613+
ASSERT_FALSE(recoverable);
1614+
// deallocate memory
1615+
allocator.deallocate(100, ptr);
1616+
}
1617+
1618+
TEST(AllocatorTest, MallocCheckedAllocateNoRecoverable) {
1619+
// Since it is a wrapper around malloc, the test consists of requesting
1620+
// memory and verifying a non-zero pointer, unchanged size, and not recoverable.
1621+
Fw::MallocAllocator allocator;
1622+
FwSizeType size = 100; // one hundred bytes
1623+
void* ptr = allocator.checkedAllocate(10, size);
1624+
ASSERT_EQ(100, size);
1625+
ASSERT_NE(ptr, nullptr);
1626+
// deallocate memory
1627+
allocator.deallocate(100, ptr);
1628+
}
1629+
1630+
TEST(AllocatorTest, MallocCheckedAllocateTrapped) {
1631+
// Since it is a wrapper around malloc, the test consists of requesting
1632+
// memory and verifying a non-zero pointer, unchanged size, and not recoverable.
1633+
Fw::MallocAllocator allocator;
1634+
bool recoverable;
1635+
FwSizeType size = std::numeric_limits<FwSizeType>::max(); // Impossible number of bytes
1636+
ASSERT_DEATH(allocator.checkedAllocate(10, size, recoverable), ".*");
1637+
}
1638+
1639+
TEST(AllocatorTest, MallocCheckedAllocateNoRecoverableTrapped) {
1640+
// Since it is a wrapper around malloc, the test consists of requesting
1641+
// memory and verifying a non-zero pointer, unchanged size, and not recoverable.
1642+
Fw::MallocAllocator allocator;
1643+
FwSizeType size = std::numeric_limits<FwSizeType>::max(); // Impossible number of bytes
1644+
ASSERT_DEATH(allocator.checkedAllocate(10, size), ".*");
1645+
}
1646+
15911647
TEST(Nominal, string_copy) {
15921648
const char* copy_string = "abc123\n"; // Length of 7
15931649
char buffer_out_test[10];

0 commit comments

Comments
 (0)