You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
S11.08 (#410 / #411) closed the FreeRTOS sweep — the third platform sweep. This story
closes out E11's class-by-class migration with the AtomicCounter family + TLS +
FatFs classes that were explicitly deferred from S11.04 – S11.08 because they don't
sit cleanly under one platform umbrella. Four classes across three Platform/
subtrees; all four are storage-cast today and get the canonical 3-TU split + SolidSyslogPoolAllocator treatment.
Class
Lines
Vtable base
Today's shape
State
StdAtomicCounter
75
AtomicCounter
Storage-cast
_Atomic uint32_t
WindowsAtomicCounter
80
AtomicCounter
Storage-cast
volatile LONG
TlsStream
460
Stream
Storage-cast
SSL_CTX*, SSL*, BIO_METHOD*, config
FatFsFile
145
File
Storage-cast
FIL, IsOpen
Out of scope per E11 epic: all of Platform/Posix/, Platform/Windows/ (bar WindowsAtomicCounter), Platform/FreeRtos/ — those are S11.06 / S11.07 / S11.08
(done). SolidSyslog core retrofit is S11.10. Wholesale MISRA storage-cast
deviation removal is S11.11.
Decisions locked in pre-raise
1. One new public GoF null — SolidSyslogNullAtomicCounter. Symmetric with the
S11.06 wave (NullDatagram, NullStream, NullFile, NullResolver) that introduced
publicly-visible nulls when more than one platform implementation shares a vtable
base. Both StdAtomicCounter (Linux/clang/gcc) and WindowsAtomicCounter (MSVC)
need a pool-exhaustion fallback; both are gated mutually-exclusive in tests
(HAVE_STDATOMIC_H / HAVE_WINDOWS_INTERLOCKED), so a TU-private fallback would
duplicate; and a future FreeRTOS atomic counter (if <stdatomic.h> isn't viable on
some port) would reach for the same fallback. Public shape now is consistent.
SolidSyslogNullAtomicCounter_Get's Increment returns 1U unconditionally —
RFC 5424 §7.3.1 requires sequenceIds in [1, 2^31-1] and never 0. Returning 1U
looks like the post-power-on / post-wrap state, which is the safest indistinguishable
behaviour.
No other new public nulls — NullStream (S11.06) covers TlsStream; NullFile
(S11.06) covers FatFsFile.
Fallback
Consumer in S11.09
Source
SolidSyslogNullAtomicCounter
StdAtomicCounter
S11.09 new
SolidSyslogNullAtomicCounter
WindowsAtomicCounter
S11.09 new
SolidSyslogNullStream
TlsStream
S11.06
SolidSyslogNullFile
FatFsFile
S11.06
2. Pool size defaults — all four at 1U. None of the four has a use case for
multiple concurrent instances in any single target today.
Class
Tunable
Default
StdAtomicCounter
SOLIDSYSLOG_STD_ATOMIC_COUNTER_POOL_SIZE
1U
WindowsAtomicCounter
SOLIDSYSLOG_WINDOWS_ATOMIC_COUNTER_POOL_SIZE
1U
TlsStream
SOLIDSYSLOG_TLS_STREAM_POOL_SIZE
1U
FatFsFile
SOLIDSYSLOG_FATFS_FILE_POOL_SIZE
1U
3. Three-TU split per class — unchanged from prior sweeps:
SolidSyslog<Class>Static.c — pool + _Create/_Destroy/IndexFromHandle
CleanupAtIndex + fallback assignment. Helpers static inline per 78c059e.
4. AtomicCounter whitebox-test access preserved. Today Tests/SolidSyslog{Std,Windows}AtomicCounterTestHelper.c reach into the production .c via #include to call StdAtomicCounter_Init / WindowsAtomicCounter_Init
for the wraparound test (positioning the counter near INT32_MAX). After the split,
the _Init helper stays in SolidSyslog<*>AtomicCounter.c alongside _Increment
(struct definition moves to *Private.h); the TestHelper continues to
whitebox-include the .c and additionally gets the include path for *Private.h.
Wraparound test mechanism unchanged.
5. TlsStream is refactor-only. Bounded handshake retry via the injected SolidSyslogSleepFunction, the BIO_METHOD lifecycle, SNI / cipher-list / trust-anchor
/ client-cert configuration, and all OpenSSL error handling preserved verbatim. The
OpenSslFake seam stays intact for unit tests.
6. FatFsFile's SOLIDSYSLOG_FATFS_FILE_SIZE of 180 intptrs is deleted along
with the public Storage typedef. The struct (carrying the full FIL with the
512-byte sector buffer) moves to the private header; sizing is validated internally
by SOLIDSYSLOG_STATIC_ASSERT in SolidSyslogFatFsFile.c. The S21.03 follow-up that
was going to make FF_MAX_SS > 512 overridable becomes simpler — the override is now
purely a pool-internal concern, not a public-API one.
7. No new MISRA suppressions. Storage-cast deviations on all four classes are removed by this story.
8. File-scope statics carry the class-prefix shape (StdAtomicCounter_InUse, StdAtomicCounter_Pool, StdAtomicCounter_Allocator) from the start.
9. INTERFACE-library shapes preserved.Platform/FatFs/CMakeLists.txt stays an
INTERFACE target — SolidSyslogFatFsFileStatic.c joins SolidSyslogFatFsFile.c in
every consumer's source list:
Bdd/Targets/FreeRtos/CMakeLists.txt
Tests/FatFs/CMakeLists.txt
Platform/Atomics/CMakeLists.txt, Platform/OpenSsl/CMakeLists.txt, and Platform/Windows/CMakeLists.txt's HAVE_WINDOWS_INTERLOCKED block all stay
PRIVATE-source — the new *Static.c is added alongside the existing entry.
Sequencing on the work branch
Recommended commit shape on refactor/s11-09-atomics-tls-fatfs-sweep:
SolidSyslog<Class>Static.c — pool + Create/Destroy/IndexFromHandle/CleanupAtIndex.
Public header — delete <Class>Storage typedef and SOLIDSYSLOG_*_SIZE
enum; drop the storage parameter from _Create (TlsStream keeps its config
parameter).
Tunable in Core/Interface/SolidSyslogTunablesDefaults.h.
Error messages in Core/Source/SolidSyslogErrorMessages.h.
CMakeLists entries for the new *Static.c TU
(Platform/<sub>/CMakeLists.txt for PRIVATE; Bdd/Targets/FreeRtos/CMakeLists.txt
and Tests/FatFs/CMakeLists.txt for FatFs INTERFACE consumers).
Existing test file — drop <*>Storage locals; switch to handle-based teardown.
New Pool TEST_GROUP — 9 tests mirroring SolidSyslogWindowsMutexPool.
AtomicCounter TestHelper include-path update for *Private.h (both Std and Windows).
CLAUDE.md audience-table row updated.
Caller updates in BDD targets:
Bdd/Targets/Linux/main.c — drop counterStorage
Bdd/Targets/Windows/BddTargetWindows.c — drop counterStorage
Bdd/Targets/FreeRtos/main.c — drop atomicCounterStorage + storeFileStorage
Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_{Posix,Winsock}Tcp.c — drop tlsStreamStorage
Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp — drop tlsStreamStorage{}
Public API changes
/* Before */structSolidSyslogAtomicCounter*SolidSyslogStdAtomicCounter_Create(SolidSyslogStdAtomicCounterStorage*);
structSolidSyslogAtomicCounter*SolidSyslogWindowsAtomicCounter_Create(SolidSyslogWindowsAtomicCounterStorage*);
structSolidSyslogFile*SolidSyslogFatFsFile_Create(SolidSyslogFatFsFileStorage*);
structSolidSyslogStream*SolidSyslogTlsStream_Create(SolidSyslogTlsStreamStorage*, conststructSolidSyslogTlsStreamConfig*);
/* After */structSolidSyslogAtomicCounter*SolidSyslogStdAtomicCounter_Create(void);
structSolidSyslogAtomicCounter*SolidSyslogWindowsAtomicCounter_Create(void);
structSolidSyslogFile*SolidSyslogFatFsFile_Create(void);
structSolidSyslogStream*SolidSyslogTlsStream_Create(conststructSolidSyslogTlsStreamConfig*);
/* New */structSolidSyslogAtomicCounter*SolidSyslogNullAtomicCounter_Get(void);
<Class>Storage typedefs and SOLIDSYSLOG_*_SIZE enums deleted from public headers.
Acceptance criteria
All four target classes migrated onto SolidSyslogPoolAllocator. Per-class *Static.c lands at ≤ ~72 lines mirroring the S11.07 / S11.08 baseline.
Public SolidSyslog{Std,Windows}AtomicCounterStorage, SolidSyslogTlsStreamStorage, SolidSyslogFatFsFileStorage types and their SOLIDSYSLOG_*_SIZE enums gone from Platform/Atomics/Interface/, Platform/Windows/Interface/, Platform/OpenSsl/Interface/, Platform/FatFs/Interface/.
SolidSyslogNullAtomicCounter lands as a new public class
(Core/Interface/SolidSyslogNullAtomicCounter.h + Core/Source/SolidSyslogNullAtomicCounter.c); Increment returns 1U.
Per-class Pool TEST_GROUP — 9 tests mirroring SolidSyslogWindowsMutexPool.
All previously existing tests continue to pass — including the AtomicCounter
wraparound test that uses the whitebox _Init helper.
TlsStream handshake/retry/SNI/cipher/cert semantics preserved verbatim; the
migration is refactor-only.
All host gates green from gcc devcontainer: debug, sanitize, coverage, tidy,
cppcheck, clang-format. Clang-debug, IWYU run via the clang container.
cppcheck-misra produces no new findings vs main. Per-class storage-cast
deviations evaporate for all four classes — record which in DEVLOG per feedback_cppcheck_misra_invariant.
Coverage at 100% line for every new and migrated file (including SolidSyslogNullAtomicCounter).
Validation step: per migrated class, re-run the full suite at SOLIDSYSLOG_<CLASS>_POOL_SIZE=3 via SOLIDSYSLOG_USER_TUNABLES_FILE.
Validated locally on MSVC per feedback_local_msvc — WindowsAtomicCounter
tests run under VS 2026 + vcpkg on the native box, not relying on CI alone.
DEVLOG entry on the work branch BEFORE the PR per feedback_devlog_in_pr, with
handoff notes for the MSVC validation pass.
SOLIDSYSLOG_FATFS_FILE_SIZE override mechanism for FF_MAX_SS > 512
(planned S21.03 follow-up — becomes simpler post-S11.09 since the size leaves the
public surface).
Memory pointers for the next session
CLAUDE.md + SKILL.md.
MEMORY.md, especially:
project_e11_static_pool_design
project_e11_three_tu_split
project_pool_allocator_helper
project_configlock_injection
feedback_storage_pattern — obsoleted per class as each migrates
SolidSyslogNullAtomicCounter_Get return type — return the base
(struct SolidSyslogAtomicCounter*) or a Self type? S11.06 nulls return the base
(SolidSyslogNullStream_Get returns SolidSyslogStream*), so follow that for
consistency. Confirm at first commit.
TlsStream Config defensive-copy — Create captures *config by value into the
slot. The integrator's SolidSyslogTlsStreamConfig lifetime requirement (must
outlive the slot until _Destroy?) is unchanged from main since the struct is
copied into the slot. Verify the contract on the public header comment matches.
Whether to fold S11.10 (SolidSyslog core retrofit) into this PR — small in
scope (pool size 1 fixed, no tunable), shares the same review surface. Default:
keep separate per epic plan; reconsider if S11.09 lands light.
Parent epic: #29
Context
S11.08 (#410 / #411) closed the FreeRTOS sweep — the third platform sweep. This story
closes out E11's class-by-class migration with the AtomicCounter family + TLS +
FatFs classes that were explicitly deferred from S11.04 – S11.08 because they don't
sit cleanly under one platform umbrella. Four classes across three
Platform/subtrees; all four are storage-cast today and get the canonical 3-TU split +
SolidSyslogPoolAllocatortreatment.StdAtomicCounter_Atomic uint32_tWindowsAtomicCountervolatile LONGTlsStreamSSL_CTX*,SSL*,BIO_METHOD*, configFatFsFileFIL,IsOpenOut of scope per E11 epic: all of
Platform/Posix/,Platform/Windows/(barWindowsAtomicCounter),Platform/FreeRtos/— those are S11.06 / S11.07 / S11.08(done).
SolidSyslogcore retrofit is S11.10. Wholesale MISRA storage-castdeviation removal is S11.11.
Decisions locked in pre-raise
1. One new public GoF null —
SolidSyslogNullAtomicCounter. Symmetric with theS11.06 wave (
NullDatagram,NullStream,NullFile,NullResolver) that introducedpublicly-visible nulls when more than one platform implementation shares a vtable
base. Both
StdAtomicCounter(Linux/clang/gcc) andWindowsAtomicCounter(MSVC)need a pool-exhaustion fallback; both are gated mutually-exclusive in tests
(
HAVE_STDATOMIC_H/HAVE_WINDOWS_INTERLOCKED), so a TU-private fallback wouldduplicate; and a future FreeRTOS atomic counter (if
<stdatomic.h>isn't viable onsome port) would reach for the same fallback. Public shape now is consistent.
SolidSyslogNullAtomicCounter_Get'sIncrementreturns1Uunconditionally —RFC 5424 §7.3.1 requires sequenceIds in
[1, 2^31-1]and never0. Returning1Ulooks like the post-power-on / post-wrap state, which is the safest indistinguishable
behaviour.
No other new public nulls —
NullStream(S11.06) coversTlsStream;NullFile(S11.06) covers
FatFsFile.SolidSyslogNullAtomicCounterSolidSyslogNullAtomicCounterSolidSyslogNullStreamSolidSyslogNullFile2. Pool size defaults — all four at 1U. None of the four has a use case for
multiple concurrent instances in any single target today.
SOLIDSYSLOG_STD_ATOMIC_COUNTER_POOL_SIZESOLIDSYSLOG_WINDOWS_ATOMIC_COUNTER_POOL_SIZESOLIDSYSLOG_TLS_STREAM_POOL_SIZESOLIDSYSLOG_FATFS_FILE_POOL_SIZE3. Three-TU split per class — unchanged from prior sweeps:
SolidSyslog<Class>.c— vtable +_Initialise(base, ...)+_Cleanup(base).SolidSyslog<Class>Private.h— concrete struct + private signatures, TU-internal.SolidSyslog<Class>Static.c— pool +_Create/_Destroy/IndexFromHandleCleanupAtIndex+ fallback assignment. Helpersstatic inlineper 78c059e.4. AtomicCounter whitebox-test access preserved. Today
Tests/SolidSyslog{Std,Windows}AtomicCounterTestHelper.creach into the production.cvia#includeto callStdAtomicCounter_Init/WindowsAtomicCounter_Initfor the wraparound test (positioning the counter near
INT32_MAX). After the split,the
_Inithelper stays inSolidSyslog<*>AtomicCounter.calongside_Increment(struct definition moves to
*Private.h); the TestHelper continues towhitebox-include the
.cand additionally gets the include path for*Private.h.Wraparound test mechanism unchanged.
5.
TlsStreamis refactor-only. Bounded handshake retry via the injectedSolidSyslogSleepFunction, the BIO_METHOD lifecycle, SNI / cipher-list / trust-anchor/ client-cert configuration, and all OpenSSL error handling preserved verbatim. The
OpenSslFake seam stays intact for unit tests.
6.
FatFsFile'sSOLIDSYSLOG_FATFS_FILE_SIZEof 180 intptrs is deleted alongwith the public Storage typedef. The struct (carrying the full
FILwith the512-byte sector buffer) moves to the private header; sizing is validated internally
by
SOLIDSYSLOG_STATIC_ASSERTinSolidSyslogFatFsFile.c. The S21.03 follow-up thatwas going to make
FF_MAX_SS > 512overridable becomes simpler — the override is nowpurely a pool-internal concern, not a public-API one.
7. No new MISRA suppressions. Storage-cast deviations on all four classes are
removed by this story.
8. File-scope statics carry the class-prefix shape (
StdAtomicCounter_InUse,StdAtomicCounter_Pool,StdAtomicCounter_Allocator) from the start.9. INTERFACE-library shapes preserved.
Platform/FatFs/CMakeLists.txtstays anINTERFACE target —
SolidSyslogFatFsFileStatic.cjoinsSolidSyslogFatFsFile.cinevery consumer's source list:
Bdd/Targets/FreeRtos/CMakeLists.txtTests/FatFs/CMakeLists.txtPlatform/Atomics/CMakeLists.txt,Platform/OpenSsl/CMakeLists.txt, andPlatform/Windows/CMakeLists.txt'sHAVE_WINDOWS_INTERLOCKEDblock all stayPRIVATE-source — the new
*Static.cis added alongside the existing entry.Sequencing on the work branch
Recommended commit shape on
refactor/s11-09-atomics-tls-fatfs-sweep:feat: S11.09 add SolidSyslogNullAtomicCounterrefactor: S11.09 migrate StdAtomicCounter onto PoolAllocatorrefactor: S11.09 migrate WindowsAtomicCounter onto PoolAllocatorrefactor: S11.09 migrate FatFsFile onto PoolAllocatorrefactor: S11.09 migrate TlsStream onto PoolAllocatordocs: update DEVLOG for S11.09Squash-merge title:
feat: S11.09 AtomicCounter family + TLS + FatFs onto PoolAllocator.Per-class scope
For each of the four classes, the migration commit lands:
SolidSyslog<Class>.c— vtable +_Initialise(base, ...)+_Cleanup(base).SolidSyslog<Class>Private.h— TU-internal struct + private signatures.SolidSyslog<Class>Static.c— pool + Create/Destroy/IndexFromHandle/CleanupAtIndex.<Class>Storagetypedef andSOLIDSYSLOG_*_SIZEenum; drop the
storageparameter from_Create(TlsStream keeps itsconfigparameter).
Core/Interface/SolidSyslogTunablesDefaults.h.Core/Source/SolidSyslogErrorMessages.h.*Static.cTU(
Platform/<sub>/CMakeLists.txtfor PRIVATE;Bdd/Targets/FreeRtos/CMakeLists.txtand
Tests/FatFs/CMakeLists.txtfor FatFs INTERFACE consumers).<*>Storagelocals; switch to handle-based teardown.SolidSyslogWindowsMutexPool.*Private.h(both Std and Windows).CLAUDE.mdaudience-table row updated.Bdd/Targets/Linux/main.c— dropcounterStorageBdd/Targets/Windows/BddTargetWindows.c— dropcounterStorageBdd/Targets/FreeRtos/main.c— dropatomicCounterStorage+storeFileStorageBdd/Targets/Common/BddTargetTlsSender_OpenSsl_{Posix,Winsock}Tcp.c— droptlsStreamStorageTests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp— droptlsStreamStorage{}Public API changes
<Class>Storagetypedefs andSOLIDSYSLOG_*_SIZEenums deleted from public headers.Acceptance criteria
SolidSyslogPoolAllocator. Per-class*Static.clands at ≤ ~72 lines mirroring the S11.07 / S11.08 baseline.SolidSyslog{Std,Windows}AtomicCounterStorage,SolidSyslogTlsStreamStorage,SolidSyslogFatFsFileStoragetypes and theirSOLIDSYSLOG_*_SIZEenums gone fromPlatform/Atomics/Interface/,Platform/Windows/Interface/,Platform/OpenSsl/Interface/,Platform/FatFs/Interface/.SolidSyslogNullAtomicCounterlands as a new public class(
Core/Interface/SolidSyslogNullAtomicCounter.h+Core/Source/SolidSyslogNullAtomicCounter.c);Incrementreturns1U.SolidSyslogWindowsMutexPool.wraparound test that uses the whitebox
_Inithelper.TlsStreamhandshake/retry/SNI/cipher/cert semantics preserved verbatim; themigration is refactor-only.
FatFsFile'sf_open/f_close/f_read/f_write/f_sync-after-write semanticspreserved verbatim.
gccdevcontainer: debug, sanitize, coverage, tidy,cppcheck, clang-format. Clang-debug, IWYU run via the
clangcontainer.deviations evaporate for all four classes — record which in DEVLOG per
feedback_cppcheck_misra_invariant.SolidSyslogNullAtomicCounter).SOLIDSYSLOG_<CLASS>_POOL_SIZE=3viaSOLIDSYSLOG_USER_TUNABLES_FILE.feedback_local_msvc—WindowsAtomicCountertests run under VS 2026 + vcpkg on the native box, not relying on CI alone.
feedback_devlog_in_pr, withhandoff notes for the MSVC validation pass.
Out of scope
SolidSyslogcore retrofit — S11.10.evaporate naturally here; the broader
D.002cleanup is S11.11).SOLIDSYSLOG_FATFS_FILE_SIZEoverride mechanism forFF_MAX_SS > 512(planned S21.03 follow-up — becomes simpler post-S11.09 since the size leaves the
public surface).
Memory pointers for the next session
CLAUDE.md+SKILL.md.MEMORY.md, especially:project_e11_static_pool_designproject_e11_three_tu_splitproject_pool_allocator_helperproject_configlock_injectionfeedback_storage_pattern— obsoleted per class as each migratesfeedback_bad_setup_contract— fallback severity vocabularyfeedback_discuss_production_changesfeedback_tdd_and_review_stylefeedback_no_premature_generalisationfeedback_cppcheck_misra_invariantfeedback_devlog_in_prfeedback_pr_templatefeedback_no_git_commit_dash_sfeedback_no_mergefeedback_local_msvc— validate MSVC locally before pushingfeedback_iwyu_local_invocationproject_header_configured_platforms— FatFs INTERFACE shape constraintOpen questions for the next session
SolidSyslogNullAtomicCounter_Getreturn type — return the base(
struct SolidSyslogAtomicCounter*) or a Self type? S11.06 nulls return the base(
SolidSyslogNullStream_GetreturnsSolidSyslogStream*), so follow that forconsistency. Confirm at first commit.
TlsStreamConfig defensive-copy — Create captures*configby value into theslot. The integrator's
SolidSyslogTlsStreamConfiglifetime requirement (mustoutlive the slot until
_Destroy?) is unchanged from main since the struct iscopied into the slot. Verify the contract on the public header comment matches.
SolidSyslogcore retrofit) into this PR — small inscope (pool size 1 fixed, no tunable), shares the same review surface. Default:
keep separate per epic plan; reconsider if S11.09 lands light.