Skip to content

S04.05: Circular buffer — bare-metal ring buffer with mutex injection #54

Description

@DavidCozens

Parent epic: #6

Portable in-memory ring buffer satisfying the SolidSyslogBuffer interface, suitable for bare-metal / RTOS targets without POSIX message queues, and as the buffer of choice for Windows.

Design

  • Storage: caller-supplied, Formatter-style variable-size pattern. Two sizing macros: SOLIDSYSLOG_CIRCULARBUFFER_STORAGE_SIZE(maxMessages) for the friendly "N max-sized messages" form, and SOLIDSYSLOG_CIRCULARBUFFER_STORAGE_SIZE_BYTES(ringBytes) for raw byte capacity (useful in tests). _Create takes storage, sizeof(storage), and the mutex. No internal malloc.
  • Record framing: each record is a uint16_t size header followed by size payload bytes. Records do not span the wrap point — wrap is handled by wrapPoint index and a no-split rule, not by record splitting. Payloads exceeding SOLIDSYSLOG_MAX_MESSAGE_SIZE are dropped at Write.
  • Overflow policy: drop-newest, silently. Matches the existing PosixMessageQueueBuffer (O_NONBLOCK + ignored mq_send return). Loss is detected SIEM-side by gaps in origin sequenceId (the mechanism that closed S04.06).
  • Read semantics: if the next record does not fit in the caller-supplied destination buffer, Read returns false with bytesRead = 0 and leaves the record queued — mirrors mq_receive EMSGSIZE semantics.
  • Concurrency: synchronization via injected SolidSyslogMutex vtable (Lock/Unlock). SolidSyslogNullMutex is the no-op default for single-task use.

Deliverables in this story

  • SolidSyslogCircularBuffer + tests (main behaviour, mutex call-pattern, small-ring boundary tests)
  • SolidSyslogMutex vtable + SolidSyslogNullMutex + tests
  • SolidSyslogPosixMutex (pthread_mutex_t) + tests
  • SolidSyslogWindowsMutex (CRITICAL_SECTION) + tests
  • Public-header audience table updated in CLAUDE.md

Out of scope

  • Wiring this buffer through any example or BDD harness — that is S13.18 (S13.18: Windows BDD exercising the portable ring buffer #244).
  • Encryption / authentication of records (might revisit if this is ever used cross-process; not today).
  • Configurable discard policy. If we ever need drop-oldest / halt at this layer, reuse SolidSyslogDiscardPolicy from BlockStore.
  • Mutex _Create initialization-failure handling (pthread_mutex_init / InitializeCriticalSection return values) — deferred to E12 (error handling), tracked in the project robustness backlog.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyStory issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions