GCC Code Coverage Report


Directory: Fw/Types/
File: MmapAllocator.hpp
Date: 2026-09-03 21:15:04
Exec Total Coverage
Lines: 25 28 89.3%
Functions: 4 4 100.0%
Branches: 12 14 85.7%

Line Branch Exec Source
1 /**
2 * \file
3 * \author Gene Merewether
4 * \brief A MemAllocator implementation class that uses mmap.
5 *
6 * \copyright
7 * Copyright 2009-2016, by the California Institute of Technology.
8 * ALL RIGHTS RESERVED. United States Government Sponsorship
9 * acknowledged.
10 *
11 */
12
13 #ifndef TYPES_MMAPALLOCATOR_HPP_
14 #define TYPES_MMAPALLOCATOR_HPP_
15
16 #include <sys/mman.h>
17 #include <unistd.h>
18 #include <Fw/DataStructures/RedBlackTreeMap.hpp>
19 #include <Fw/Logger/Logger.hpp>
20 #include <Fw/Types/MemAllocator.hpp>
21 #include <cerrno>
22
23 namespace Fw {
24
25 //! Fw::MmapAllocator is an implementation of the Fw::MemAllocator interface that backs memory with a read and write
26 //! capable anonymous memory mapped region.
27 //!
28 //! \param C - Number of allocations supported by this allocator.
29 //! munmap needs the size of the original mapping. MmapAllocator keeps these sizes in a Map structure
30 //! with a compile time limit on allocations
31 //!
32 template <FwSizeType C>
33 class MmapAllocator : public MemAllocator {
34 public:
35 //! Constructor with one default argument
36 //!
37 explicit MmapAllocator(int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS);
38 //! Destructor with no arguments
39 virtual ~MmapAllocator();
40
41 //! Allocate memory using the mmap allocator
42 //! \param identifier: identifier to use with allocation
43 //! \param size: size of memory to be allocated
44 //! \param recoverable: (output) is this memory recoverable after a reset. Always false for mmap.
45 //! \param alignment - alignment requirement for the allocation. Default: maximum alignment defined by C++.
46 //! \return the pointer to memory. Zero if unable to allocate
47 void* allocate(const FwEnumStoreType identifier,
48 FwSizeType& size,
49 bool& recoverable,
50 FwSizeType alignment = alignof(std::max_align_t)) override;
51
52 //! Deallocation of memory using the mmap allocator
53 //! \param identifier: identifier used at allocation
54 //! \param ptr: pointer to memory being deallocated
55 void deallocate(const FwEnumStoreType identifier, void* ptr) override;
56
57 private:
58 //! Store sizes of previous allocations to use with deallocate
59 RedBlackTreeMap<intptr_t, size_t, C> m_size_map;
60
61 //! Store flags to pass to mmap
62 const int m_mmap_flags;
63 };
64
65 template <FwSizeType C>
66
1/1
✓ Branch 12 taken 3 times.
3 MmapAllocator<C>::MmapAllocator(int mmap_flags) : m_size_map(), m_mmap_flags(mmap_flags) {}
67
68 template <FwSizeType C>
69 6 MmapAllocator<C>::~MmapAllocator() {}
70
71 template <FwSizeType C>
72 7 void* MmapAllocator<C>::allocate(const FwEnumStoreType identifier,
73 FwSizeType& size,
74 bool& recoverable,
75 FwSizeType alignment) {
76 // mmap memory is never recoverable
77 7 recoverable = false;
78
79 // mmap allocates pages at a virtual boundary. Alignment is guaranteed
80 // up to the page size
81
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
7 if (alignment > static_cast<FwSizeType>(sysconf(_SC_PAGESIZE))) {
82
1/1
✓ Branch 2 taken 1 times.
1 Fw::Logger::log("Unable to allocate. Alignment request (%ld) > PAGE_SIZE (%ld)\n", alignment,
83 sysconf(_SC_PAGESIZE));
84 1 size = 0;
85 1 return nullptr;
86 }
87
88
4/4
✓ Branch 6 taken 6 times.
✓ Branch 14 taken 6 times.
✓ Branch 16 taken 1 times.
✓ Branch 17 taken 5 times.
6 if (m_size_map.getCapacity() == m_size_map.getSize()) {
89
1/1
✓ Branch 1 taken 1 times.
1 Fw::Logger::log("Unable to allocate. MmapAllocator out of size_map slots\n");
90 1 size = 0;
91 1 return nullptr;
92 }
93
94 5 void* addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, m_mmap_flags, -1, 0);
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (addr == MAP_FAILED) {
96 Fw::Logger::log("Unable to allocate. mmap syscall failed. Errno (%ld)\n", errno);
97 size = 0;
98 return nullptr;
99 }
100
101
1/1
✓ Branch 7 taken 5 times.
5 Fw::Success ok = m_size_map.insert(reinterpret_cast<intptr_t>(addr), size);
102 5 FW_ASSERT(ok == Fw::Success::SUCCESS, ok);
103
104 5 return addr;
105 5 }
106
107 template <FwSizeType C>
108 5 void MmapAllocator<C>::deallocate(const FwEnumStoreType identifier, void* ptr) {
109 5 size_t alloc_size = 0;
110
1/1
✓ Branch 6 taken 5 times.
5 Fw::Success ok = m_size_map.remove(reinterpret_cast<intptr_t>(ptr), alloc_size);
111 5 FW_ASSERT(ok == Fw::Success::SUCCESS, ok);
112
113 5 int stat = munmap(ptr, alloc_size);
114 5 FW_ASSERT(stat == 0, stat);
115 10 }
116
117 } /* namespace Fw */
118
119 #endif /* TYPES_MMAPALLOCATOR_HPP_ */
120