diff --git a/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.cpp b/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.cpp index 7c3cc2df..1264baf7 100644 --- a/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.cpp +++ b/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.cpp @@ -15,17 +15,26 @@ namespace Baremetal { TlmLinearChan::TlmLinearChan(const char* name) : TlmLinearChanComponentBase(name), m_memId(0), m_setupDone(false) {} -TlmLinearChan::~TlmLinearChan() { - if (this->m_tlmEntries != nullptr) { +TlmLinearChan::~TlmLinearChan() {} + +void TlmLinearChan::deinit() { + if (this->m_setupDone) { + FW_ASSERT(this->m_tlmEntries != nullptr); + FW_ASSERT(this->m_allocator != nullptr); + // First destruct the TLM entry structs for (auto i = 0; i < TLMCHAN_HASH_BUCKETS; i++) { this->m_tlmEntries[i].~TlmEntry(); } // Then deallocate the memory - if (this->m_allocator != nullptr) { - this->m_allocator->deallocate(this->m_memId, this->m_tlmEntries); - } + this->m_allocator->deallocate(this->m_memId, this->m_tlmEntries); + + this->m_tlmEntries = nullptr; + this->m_allocator = nullptr; + this->m_setupDone = false; } + + TlmLinearChanComponentBase::deinit(); } void TlmLinearChan::init(FwSizeType queueDepth, /*!< The queue depth*/ diff --git a/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.hpp b/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.hpp index decb5557..4bec58b2 100644 --- a/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.hpp +++ b/fprime-baremetal/Svc/TlmLinearChan/TlmLinearChan.hpp @@ -23,6 +23,7 @@ class TlmLinearChan : public TlmLinearChanComponentBase { void init(FwSizeType queueDepth, /*!< The queue depth*/ FwEnumStoreType instance /*!< The instance number*/ ); + void deinit() override; // NOTE: setup() should be called before init() b/c init() uses values set by setup() void setup(FwEnumStoreType memId, //!< Memory segment identifier Fw::MemAllocator& allocator //!< Memory allocator diff --git a/fprime-baremetal/Svc/TlmLinearChan/test/ut/TestMain.cpp b/fprime-baremetal/Svc/TlmLinearChan/test/ut/TestMain.cpp index 602f72c1..0b863744 100644 --- a/fprime-baremetal/Svc/TlmLinearChan/test/ut/TestMain.cpp +++ b/fprime-baremetal/Svc/TlmLinearChan/test/ut/TestMain.cpp @@ -4,8 +4,39 @@ #include #include +#include #include "TlmLinearChanTester.hpp" +namespace { + +class TrackingAllocator final : public Fw::MallocAllocator { + public: + TrackingAllocator() + : m_deallocateCount(0), m_lastAllocate(nullptr), m_lastDeallocate(nullptr), m_lastDeallocateId(0) {} + + void* allocate(const FwEnumStoreType identifier, + FwSizeType& size, + bool& recoverable, + FwSizeType alignment = alignof(std::max_align_t)) override { + this->m_lastAllocate = Fw::MallocAllocator::allocate(identifier, size, recoverable, alignment); + return this->m_lastAllocate; + } + + void deallocate(const FwEnumStoreType identifier, void* ptr) override { + this->m_deallocateCount++; + this->m_lastDeallocateId = identifier; + this->m_lastDeallocate = ptr; + Fw::MallocAllocator::deallocate(identifier, ptr); + } + + FwSizeType m_deallocateCount; + void* m_lastAllocate; + void* m_lastDeallocate; + FwEnumStoreType m_lastDeallocateId; +}; + +} // namespace + TEST(TlmLinearChanTest, InitTest) { Baremetal::TlmLinearChanTester tester; } @@ -39,6 +70,24 @@ TEST(TlmLinearChanTest, OffNominal) { tester.runOffNominal(); } +TEST(TlmLinearChanTest, DeinitReleasesAllocatorStorage) { + TrackingAllocator allocator; + { + Baremetal::TlmLinearChan component("TlmLinearChan"); + component.setup(42, allocator); + component.init(10, 0); + + ASSERT_EQ(0, allocator.m_deallocateCount); + component.deinit(); + + EXPECT_EQ(1, allocator.m_deallocateCount); + EXPECT_EQ(42, allocator.m_lastDeallocateId); + EXPECT_EQ(allocator.m_lastAllocate, allocator.m_lastDeallocate); + } + + EXPECT_EQ(1, allocator.m_deallocateCount); +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/fprime-baremetal/Svc/TlmLinearChan/test/ut/TlmLinearChanTester.hpp b/fprime-baremetal/Svc/TlmLinearChan/test/ut/TlmLinearChanTester.hpp index 4c2cc278..5d0a74ca 100644 --- a/fprime-baremetal/Svc/TlmLinearChan/test/ut/TlmLinearChanTester.hpp +++ b/fprime-baremetal/Svc/TlmLinearChan/test/ut/TlmLinearChanTester.hpp @@ -88,8 +88,6 @@ class TlmLinearChanTester : public TlmLinearChanGTestBase { // Variables // ---------------------------------------------------------------------- - // Note: This MUST be declared before 'component' or it will be destroyed - // before the component can deallocate its memory. Fw::MallocAllocator m_mallocator; //! The component under test