GCC Code Coverage Report


Directory: lib/fprime-samd/fprime-samd/
File: Svc/StaticMallocator/StaticMallocator.hpp
Date: 2026-09-26 00:05:09
Exec Total Coverage
Lines: 0 16 0.0%
Functions: 0 4 0.0%
Branches: 0 18 0.0%

Line Branch Exec Source
1 /**
2 * \file
3 * \author A. Tumbar
4 * \brief A MemAllocator implementation class that uses static memory buckets.
5 *
6 * \copyright
7 * Copyright 2026, by the California Institute of Technology.
8 * ALL RIGHTS RESERVED. United States Government Sponsorship
9 * acknowledged.
10 *
11 */
12
13 #ifndef SAMD21_MALLOCALLOCATOR_HPP
14 #define SAMD21_MALLOCALLOCATOR_HPP
15
16 #include <Fw/Types/MemAllocator.hpp>
17 #include <cstddef>
18 #include "Fw/Types/Assert.hpp"
19 #include "config/FwAssertArgTypeAliasAc.h"
20 #include "config/FwEnumStoreTypeAliasAc.h"
21
22 namespace Samd21 {
23
24 //! \brief static memory based memory allocator
25 //!
26 //! This class implements a memory allocator that uses static memory buckets.
27 template <size_t BUCKET_SIZE, FwEnumStoreType IDENT>
28 class StaticMallocator : public Fw::MemAllocator {
29 public:
30 static_assert(BUCKET_SIZE % 8 == 0, "Bucket size must a multiple of 8");
31
32 ✗ StaticMallocator() = default;
33 ✗ virtual ~StaticMallocator() = default;
34
35 //! Allocate memory
36 //!
37 //! Allocate memory using malloc(). The identifier is unused and memory is never recoverable.
38 //! malloc() guarantees alignment for any type and so does this allocator. It will not respect smaller alignments.
39 //!
40 //! \param identifier the allocating entity identifier (not used)
41 //! \param size the requested size (not changed)
42 //! \param recoverable - flag to indicate the memory could be recoverable (always set to false)
43 //! \param alignment - alignment requirement for the allocation. Default: maximum alignment defined by C++.
44 //! \return the pointer to memory. Zero if unable to allocate.
45 ✗ void* allocate(const FwEnumStoreType identifier,
46 FwSizeType& size,
47 bool& recoverable,
48 FwSizeType alignment = alignof(std::max_align_t)) override {
49 ✗ FW_ASSERT(identifier == IDENT, static_cast<FwAssertArgType>(identifier), static_cast<FwAssertArgType>(IDENT));
50 ✗ FW_ASSERT(size <= BUCKET_SIZE, static_cast<FwAssertArgType>(size), static_cast<FwAssertArgType>(BUCKET_SIZE));
51 // `data` is declared alignas(std::max_align_t), so the bound here is exactly the
52 // default argument above. It used to read `alignment <= 8`, which made the DEFAULT
53 // call self-inconsistent on any host where alignof(std::max_align_t) is 16 -- true
54 // of Linux x86-64, where `long double` is 16-byte aligned. Darwin arm64 has it at
55 // 8, so the bug was invisible there and only surfaced when a unit test ran on
56 // Linux. Keep this comparing against the same expression `data` is aligned to.
57 ✗ FW_ASSERT(alignment <= alignof(std::max_align_t), static_cast<FwAssertArgType>(alignment));
58 ✗ FW_ASSERT(!used);
59
60 ✗ recoverable = true;
61 ✗ this->used = true;
62 ✗ return reinterpret_cast<void*>(this->data);
63 }
64 //! Deallocate memory
65 //!
66 //! Deallocate memory previously allocated by allocate() using free(). The identifier is unused but should still
67 //! match the original call.
68 //!
69 //! \param identifier the memory segment identifier (not used)
70 //! \param ptr the pointer to memory returned by allocate()
71 ✗ void deallocate(const FwEnumStoreType identifier, void* ptr) override {
72 ✗ FW_ASSERT(identifier == IDENT, static_cast<FwAssertArgType>(identifier), static_cast<FwAssertArgType>(IDENT));
73 ✗ FW_ASSERT(used);
74 ✗ FW_ASSERT(ptr == reinterpret_cast<void*>(this->data));
75 ✗ this->used = false;
76 ✗ }
77
78 private:
79 // U64 for 64-bit alignment, and alignas() on top of it so the storage really does
80 // satisfy the alignment this class advertises as its default argument. On the SAMD21
81 // (arm-none-eabi, 32-bit) alignof(std::max_align_t) is 8 and the U64 array is already
82 // 8-aligned, so this costs nothing on target; it only widens the alignment on hosts
83 // where max_align_t is 16, i.e. in unit tests.
84 alignas(std::max_align_t) U64 data[BUCKET_SIZE / 8];
85 bool used = false;
86 };
87
88 } // namespace Samd21
89
90 #endif /* SAMD21_MALLOCALLOCATOR_HPP */
91