feat: S11.02 extract PoolAllocator helper and migrate CircularBuffer#396
Conversation
TU-internal helper that owns the slot-walk and per-iteration LockConfig over a caller-supplied bool[]. Two operations + a static-inline predicate: - AcquireFirstFree: locks per probe; first claim wins; Count on exhaustion. - FreeIfInUse: locks once; invokes cleanup INSIDE the lock before clearing InUse; the lock-held-during-cleanup invariant prevents a concurrent Acquire from grabbing the slot mid-cleanup and racing Initialise vs Cleanup on the same memory. - IndexIsValid: static-inline predicate over Count. Not wired into CircularBufferStatic yet -- the migration is the next commit. 100% line coverage; zero new MISRA findings. Refs #395.
Drops 10 file-scope helpers (AcquireFirstFree/AcquireIfFree/Acquire/ PoolItemIsFree/PoolItemIsInUse/MarkInUse/MarkFree/HandleFromIndex/ HandleIsValid/FreeIfInUse) and retires the `struct Slot` wrapper. `Pool` is now a bare array of SolidSyslogCircularBuffer; the `InUse[]` flags live alongside it and are owned by a TU-static `SolidSyslogPoolAllocator` instance. Public API (_Create / _Destroy signatures) and per-instance state (SolidSyslogCircularBuffer struct, Initialise / Cleanup contracts) are byte-identical. The existing SolidSyslogCircularBufferTest suite passes unchanged, including the lock-count assertions that pin the per-probe LockConfig invariant -- the helper preserves that behaviour exactly. What stays per-class: IndexFromHandle (the reverse lookup is the one genuinely typed bit), CleanupAtIndex (3-line bridge from the helper's typeless callback to CircularBuffer_Cleanup), and the Fallback vtable. Two helpers plus two vtable entries -- the rest is the public API. Validated by running the full test suite at SOLIDSYSLOG_CIRCULAR_BUFFER_POOL_SIZE=3 (1139 tests pass; default POOL_SIZE=1 also green). Zero new cppcheck-misra findings (count 60 vs 61 pre-migration -- one fewer line eligible for an 8.9 diagnostic). 100% line coverage on both SolidSyslogCircularBufferStatic.c and SolidSyslogPoolAllocator.c. Refs #395.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThis PR extracts a TU-internal pool allocator helper ( ChangesPool Allocator Extraction and CircularBuffer Migration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
☀️ Quality Summary 🚦 build-linux-gcc: 100% successful (✔️ 1145 passed, 🙈 2 skipped) Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result. |
Purpose
Closes #395.
S11.01 (#394) landed the E11 canonical pool pattern in
SolidSyslogCircularBufferStatic.c— 13 pool-management functions plus astruct Slotwrapper. Every other E11 class (BlockStore, StreamSender, the Platform Mutex/Stream/Datagram/File family, AtomicCounter, TLS, FatFs, …) is about to copy that same shape. S11.02 hoists everything except the per-class reverse lookup into one TU-internalSolidSyslogPoolAllocatorhelper, so each*Static.clands at ~3 functions instead of ~13.Change Description
New helper (
Core/Source/SolidSyslogPoolAllocator.{h,c}, TU-internal — never inCore/Interface/):_AcquireFirstFree(self)— walks the pool withLockConfigwrapping every per-slot probe; returns first claimed index orCounton exhaustion. Matches S11.01's locking invariant exactly._FreeIfInUse(self, index, cleanup, ctx)— locks once; invokescleanupinside the lock before clearingInUse. The lock-held-during-cleanup invariant prevents a concurrent_AcquireFirstFreefrom grabbing the slot mid-cleanup and racingInitialisevsCleanupon the same memory._IndexIsValid(self, index)— static-inline predicate.Struct is just
{ bool* InUse; size_t Count; }— each*Static.cdeclares the array and the allocator at file scope. No_Createfor the helper, no storage cast anywhere.Migration of
CircularBufferStatic.c:struct Slotretired —Poolis bareSolidSyslogCircularBuffer[],InUse[]separate.AcquireFirstFree,AcquireIfFree,Acquire,PoolItemIsFree,PoolItemIsInUse,MarkInUse,MarkFree,HandleFromIndex,HandleIsValid,FreeIfInUse)._Create,_Destroy,IndexFromHandle(reverse lookup — hoisting needed a typeless callback that would break the no-cast invariant),CleanupAtIndex(3-line bridge), and the twoFallback_*vtable entries.Decisions kept from the design discussion:
SOLIDSYSLOG_ERROR_MSG_<CLASS>_POOL_EXHAUSTEDstring._Create/_Destroypublic signatures byte-identical to pre-migration.Test Evidence
New
Tests/SolidSyslogPoolAllocatorTest.cpp— 12 tests across five behaviours, driven happy-then-locking:IndexIsValidtrue/false.AcquireFirstFreeempty / walks-past-in-use / exhausted-returns-Count.FreeIfInUsehappy-with-cleanup / already-free-skips-cleanup / NULL-cleanup-still-frees.Acquireonce for one probe,AcquirePOOL_SIZEtimes for full pool,Freeexactly once.LockCount - UnlockCountat the moment of invocation and asserts it is exactly 1. Would catch any regression that moves cleanup out of the critical section.Regression net:
Tests/SolidSyslogCircularBufferTest.cppuntouched — all 9 Pool tests includingCreateAcquiresAndReleasesConfigLockOnFirstFreeSlot,CreateLocksOncePerSlotProbedWhenPoolIsFull,DestroyOfPooledHandleLocksOnce,DestroyOfUnknownHandleDoesNotLock,DestroyOfStaleHandleReportsWarningpass against the new implementation.Validation step (AC #7): full suite re-run at
SOLIDSYSLOG_CIRCULAR_BUFFER_POOL_SIZE=3— 1139 tests pass (defaultPOOL_SIZE=1also green).Coverage: 100% line on both
SolidSyslogPoolAllocator.cand the migratedSolidSyslogCircularBufferStatic.c.cppcheck-misra: 60 hits (was 61 pre-migration baseline — one fewer line eligible for an 8.9 diagnostic). Zero new findings against any of the three modified files.
Areas Affected
Core/Source/SolidSyslogPoolAllocator.{h,c}— new TU-internal helper.Core/Source/SolidSyslogCircularBufferStatic.c— rewritten against the helper.Tests/SolidSyslogPoolAllocatorTest.cpp— new.Core/Source/CMakeLists.txt,Tests/CMakeLists.txt— one-line additions each.DEVLOG.md— session entry.No public-header or integrator-facing change. Public
SolidSyslogCircularBuffer_Create/_Destroysignatures byte-identical. BDD targets and examples unaffected.🤖 Generated with Claude Code
Summary by CodeRabbit
Refactor
Tests
Chores