[routing-manager] use OwningList for Router and Entry lists (#10214)

This change leverages `OwningList<>` to manage discovered routers and
prefix entries within `RoutingManager`. This ensures automatic
deallocation of these items, streamlining memory management. It works
independently of whether the items are heap-allocated or from a
`Pool`.
This commit is contained in:
Abtin Keshavarzian
2024-05-08 19:53:25 -07:00
committed by GitHub
parent 8e3f51da84
commit 74573b5d3f
2 changed files with 69 additions and 55 deletions
+51 -45
View File
@@ -1199,6 +1199,32 @@ exit:
return;
}
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
RoutingManager::DiscoveredPrefixTable::Router *RoutingManager::DiscoveredPrefixTable::AllocateRouter(void)
{
Router *router = mRouterPool.Allocate();
VerifyOrExit(router != nullptr);
router->Init(GetInstance());
exit:
return router;
}
RoutingManager::DiscoveredPrefixTable::Entry *RoutingManager::DiscoveredPrefixTable::AllocateEntry(void)
{
Entry *entry = mEntryPool.Allocate();
VerifyOrExit(entry != nullptr);
entry->Init(GetInstance());
exit:
return entry;
}
#endif // !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
bool RoutingManager::DiscoveredPrefixTable::Contains(const Entry::Checker &aChecker) const
{
bool contains = false;
@@ -1270,16 +1296,15 @@ void RoutingManager::DiscoveredPrefixTable::RemovePrefix(const Entry::Matcher &a
{
// Removes all entries matching a given prefix from the table.
LinkedList<Entry> removedEntries;
bool didRemove = false;
for (Router &router : mRouters)
{
router.mEntries.RemoveAllMatching(aMatcher, removedEntries);
didRemove |= router.mEntries.RemoveAndFreeAllMatching(aMatcher);
}
VerifyOrExit(!removedEntries.IsEmpty());
VerifyOrExit(didRemove);
FreeEntries(removedEntries);
RemoveRoutersWithNoEntriesOrFlags();
SignalTableChanged();
@@ -1292,12 +1317,7 @@ void RoutingManager::DiscoveredPrefixTable::RemoveAllEntries(void)
{
// Remove all entries from the table.
for (Router &router : mRouters)
{
FreeEntries(router.mEntries);
}
FreeRouters(mRouters);
mRouters.Free();
mEntryTimer.Stop();
SignalTableChanged();
@@ -1398,58 +1418,29 @@ TimeMilli RoutingManager::DiscoveredPrefixTable::CalculateNextStaleTime(TimeMill
void RoutingManager::DiscoveredPrefixTable::RemoveRoutersWithNoEntriesOrFlags(void)
{
LinkedList<Router> routersToFree;
mRouters.RemoveAllMatching(Router::kContainsNoEntriesOrFlags, routersToFree);
FreeRouters(routersToFree);
}
void RoutingManager::DiscoveredPrefixTable::FreeRouters(LinkedList<Router> &aRouters)
{
// Frees all routers in the given list `aRouters`
Router *router;
while ((router = aRouters.Pop()) != nullptr)
{
FreeRouter(*router);
}
}
void RoutingManager::DiscoveredPrefixTable::FreeEntries(LinkedList<Entry> &aEntries)
{
// Frees all entries in the given list `aEntries`.
Entry *entry;
while ((entry = aEntries.Pop()) != nullptr)
{
FreeEntry(*entry);
}
mRouters.RemoveAndFreeAllMatching(Router::kContainsNoEntriesOrFlags);
}
void RoutingManager::DiscoveredPrefixTable::HandleEntryTimer(void) { RemoveExpiredEntries(); }
void RoutingManager::DiscoveredPrefixTable::RemoveExpiredEntries(void)
{
TimeMilli now = TimerMilli::GetNow();
TimeMilli nextExpireTime = now.GetDistantFuture();
LinkedList<Entry> expiredEntries;
TimeMilli now = TimerMilli::GetNow();
TimeMilli nextExpireTime = now.GetDistantFuture();
bool didRemove = false;
for (Router &router : mRouters)
{
router.mEntries.RemoveAllMatching(Entry::ExpirationChecker(now), expiredEntries);
didRemove |= router.mEntries.RemoveAndFreeAllMatching(Entry::ExpirationChecker(now));
}
RemoveRoutersWithNoEntriesOrFlags();
if (!expiredEntries.IsEmpty())
if (didRemove)
{
SignalTableChanged();
}
FreeEntries(expiredEntries);
// Determine the next expire time and schedule timer.
for (const Router &router : mRouters)
@@ -1808,6 +1799,13 @@ TimeMilli RoutingManager::DiscoveredPrefixTable::Entry::CalculateExpirationTime(
return mLastUpdateTime + Time::SecToMsec(Min(aLifetime, kMaxLifetime));
}
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
void RoutingManager::DiscoveredPrefixTable::Entry::Free(void)
{
Get<RoutingManager>().mDiscoveredPrefixTable.mEntryPool.Free(*this);
}
#endif
//---------------------------------------------------------------------------------------------------------------------
// DiscoveredPrefixTable::Router
@@ -1840,6 +1838,14 @@ void RoutingManager::DiscoveredPrefixTable::Router::CopyInfoTo(RouterEntry &aEnt
aEntry.mStubRouterFlag = mStubRouterFlag;
}
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
void RoutingManager::DiscoveredPrefixTable::Router::Free(void)
{
mEntries.Free();
Get<RoutingManager>().mDiscoveredPrefixTable.mRouterPool.Free(*this);
}
#endif
//---------------------------------------------------------------------------------------------------------------------
// FavoredOmrPrefix
+18 -10
View File
@@ -62,6 +62,7 @@
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/notifier.hpp"
#include "common/owning_list.hpp"
#include "common/pool.hpp"
#include "common/string.hpp"
#include "common/timer.hpp"
@@ -700,6 +701,8 @@ private:
public Unequatable<Entry>,
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
public Heap::Allocatable<Entry>,
#else
public InstanceLocatorInit,
#endif
private Clearable<Entry>
{
@@ -757,6 +760,10 @@ private:
TimeMilli mNow;
};
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
void Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
void Free(void);
#endif
void SetFrom(const RouterAdvert::Header &aRaHeader);
void SetFrom(const PrefixInfoOption &aPio);
void SetFrom(const RouteInfoOption &aRio);
@@ -804,6 +811,8 @@ private:
struct Router : public LinkedListEntry<Router>,
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
public Heap::Allocatable<Router>,
#else
public InstanceLocatorInit,
#endif
public Clearable<Router>
{
@@ -823,13 +832,18 @@ private:
kContainsNoEntriesOrFlags
};
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
void Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
void Free(void);
#endif
bool Matches(const Ip6::Address &aAddress) const { return aAddress == mAddress; }
bool Matches(EmptyChecker aChecker) const;
void CopyInfoTo(RouterEntry &aEntry) const;
Router *mNext;
Ip6::Address mAddress;
LinkedList<Entry> mEntries;
OwningList<Entry> mEntries;
TimeMilli mTimeout;
uint8_t mNsProbeCount;
bool mManagedAddressConfigFlag : 1;
@@ -867,8 +881,6 @@ private:
void RemovePrefix(const Entry::Matcher &aMatcher);
void RemoveOrDeprecateEntriesFromInactiveRouters(void);
void RemoveRoutersWithNoEntriesOrFlags(void);
void FreeRouters(LinkedList<Router> &aRouters);
void FreeEntries(LinkedList<Entry> &aEntries);
void UpdateNetworkDataOnChangeTo(Entry &aEntry);
void RemoveExpiredEntries(void);
void SignalTableChanged(void);
@@ -877,20 +889,16 @@ private:
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
Router *AllocateRouter(void) { return Router::Allocate(); }
Entry *AllocateEntry(void) { return Entry::Allocate(); }
void FreeRouter(Router &aRouter) { aRouter.Free(); }
void FreeEntry(Entry &aEntry) { aEntry.Free(); }
#else
Router *AllocateRouter(void) { return mRouterPool.Allocate(); }
Entry *AllocateEntry(void) { return mEntryPool.Allocate(); }
void FreeRouter(Router &aRouter) { mRouterPool.Free(aRouter); }
void FreeEntry(Entry &aEntry) { mEntryPool.Free(aEntry); }
Router *AllocateRouter(void);
Entry *AllocateEntry(void);
#endif
using SignalTask = TaskletIn<RoutingManager, &RoutingManager::HandleDiscoveredPrefixTableChanged>;
using EntryTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleDiscoveredPrefixTableEntryTimer>;
using RouterTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleDiscoveredPrefixTableRouterTimer>;
LinkedList<Router> mRouters;
OwningList<Router> mRouters;
EntryTimer mEntryTimer;
RouterTimer mRouterTimer;
SignalTask mSignalTask;