Skip to content

feat: S12.15 example service thread yields 1 ms per tick#285

Merged
DavidCozens merged 2 commits into
mainfrom
feat/example-service-thread-yield
May 7, 2026
Merged

feat: S12.15 example service thread yields 1 ms per tick#285
DavidCozens merged 2 commits into
mainfrom
feat/example-service-thread-yield

Conversation

@DavidCozens

@DavidCozens DavidCozens commented May 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • ExampleServiceThread_Run now takes an injected SolidSyslogSleepFunction and sleeps 1 ms unconditionally after every SolidSyslog_Service() call. Replaces the busy-spin that pegged CPU at 100% when buffer and store were empty.
  • Example/Threaded/main.c (Linux) wires SolidSyslogPosixSleep; Example/Windows/SolidSyslogWindowsExample.c wires SolidSyslogWindowsSleep.
  • Library API is unchanged — this lives entirely in Example/Common/ and the per-platform mains.

The original story text suggested #ifdef _WIN32 for the platform sleep, but SolidSyslogSleepFunction and the POSIX/Windows wirings already exist (added for the TLS handshake retry), so injection was the simpler path. Issue body updated to reflect this.

A future story can investigate signalling-based fully-idle wait (eventfd / SetEvent / RTOS task notifications via the buffer abstraction) — out of scope here.

Test plan

  • Tests/Example/ExampleServiceThreadTest.cppSleepFake mirrors the pattern in SolidSyslogTlsStreamTest.cpp; the fake flips the shutdown flag on first call so a new test YieldsOneMillisecondAfterEachServiceTick proves the yield happens once per tick at 1 ms
  • Linux gcc / clang / sanitize / coverage / clang-tidy / cppcheck / clang-format — all green via the devcontainer
  • Coverage 100% lines / 100% functions
  • MSVC built clean on the Windows host; SolidSyslogTests.exe ran 973/973
  • CI to run the BDD jobs and Windows MSVC build

Closes #277

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Example service threads now implement idle-yield behavior to prevent busy-spinning when buffers are empty, sleeping 1 ms after each service tick.
  • Tests

    • Added test verification for service thread idle-yield behavior.

ExampleServiceThread_Run takes an injected SolidSyslogSleepFunction and
sleeps 1 ms unconditionally after every SolidSyslog_Service call,
replacing the busy-spin that hammered the CPU at 100% when the buffer
and store were empty. POSIX and Windows mains pass SolidSyslogPosixSleep
and SolidSyslogWindowsSleep respectively. Library API unchanged.
@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Rate limit exceeded

@DavidCozens has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 52 minutes and 1 second before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7c950478-2719-4c7f-a8f3-7403f022abc3

📥 Commits

Reviewing files that changed from the base of the PR and between 771eeb5 and 95049be.

📒 Files selected for processing (1)
  • Tests/Example/ExampleServiceThreadTest.cpp
📝 Walkthrough

Walkthrough

This PR implements an idle-yield optimization for the example service thread. The run loop now accepts a sleep callback and yields 1 ms unconditionally after each service tick, replacing the previous busy-spin behavior. POSIX and Windows example entrypoints wire platform sleep functions, and a new test verifies the yield occurs exactly once per iteration.

Changes

Service Thread Idle Yield

Layer / File(s) Summary
Function Signature & Type Definition
Example/Common/ExampleServiceThread.h
ExampleServiceThread_Run signature extended to accept SolidSyslogSleepFunction sleep callback parameter; header includes SolidSyslogSleep.h for type definition.
Core Service Loop
Example/Common/ExampleServiceThread.c
Adds IDLE_YIELD_MILLISECONDS constant (1 ms); service loop now calls injected sleep callback after each SolidSyslog_Service() invocation.
POSIX Example Integration
Example/Threaded/main.c
ServiceThreadEntry wires SolidSyslogPosixSleep into ExampleServiceThread_Run call.
Windows Example Integration
Example/Windows/SolidSyslogWindowsExample.c
ServiceThreadEntry wires SolidSyslogWindowsSleep into ExampleServiceThread_Run call.
Test Verification & Documentation
Tests/Example/ExampleServiceThreadTest.cpp, DEVLOG.md
Introduces SleepFake callback with global state tracking (g_sleepCallCount, g_lastSleepMs, g_sleepShutdown); new test "YieldsOneMillisecondAfterEachServiceTick" verifies single 1 ms yield per service iteration; DEVLOG.md documents the S12.15 feature entry.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • DavidCozens/solid-syslog#264: Previously integrated ExampleServiceThread.c into the Windows example and wired the service-thread entrypoint—both that PR and this one modify the same service-thread callback pattern.
  • DavidCozens/solid-syslog#153: Both PRs modify the Windows example entrypoint and service-thread initialization—the earlier PR added the initial Windows example entrypoint.

Poem

🐰 A thread that yielded once, now yields with grace,
One millisecond pauses at a steady pace,
No more the busy spin, no CPU despair,
The loop breathes easy, giving cycles to spare! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: injecting a sleep function into the example service thread to yield 1 ms per tick, directly addressing the busy-spin fix in S12.15.
Description check ✅ Passed The description covers Purpose (why—100% CPU busy-spin), Change (function signature, sleep injection, platform wirings), Test Evidence (SleepFake test), and Areas Affected (Example code only, library API unchanged). All template sections are substantively filled.
Linked Issues check ✅ Passed All coding requirements from #277 are met: ExampleServiceThread_Run accepts injected SolidSyslogSleepFunction [#277], sleeps 1 ms unconditionally after each SolidSyslog_Service() call [#277], reuses existing sleep wirings without #ifdefs [#277], keeps library API unchanged [#277], and adds SleepFake test verifying 1 ms yield per tick [#277].
Out of Scope Changes check ✅ Passed All changes directly serve #277 requirements: DEVLOG entry documents the fix, Example/Common/ExampleServiceThread files implement sleep injection, platform mains wire sleep functions, and test file verifies the yield. No changes fall outside the stated scope of fixing busy-spin via sleep injection.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/example-service-thread-yield

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Tests/Example/ExampleServiceThreadTest.cpp (1)

19-21: ⚡ Quick win

Rename g_-prefixed test globals to plain camelCase.

These globals use a prefix style that conflicts with the project naming rule; please rename to camelCase (e.g., sleepCallCount, lastSleepMs, sleepShutdown).

As per coding guidelines, “Variables must use camelCase naming” and “Do not use … prefixes (m_, _, etc.).”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/Example/ExampleServiceThreadTest.cpp` around lines 19 - 21, Rename the
test globals g_sleepCallCount, g_lastSleepMs, and g_sleepShutdown to camelCase
names (sleepCallCount, lastSleepMs, sleepShutdown) to comply with project naming
rules; update every reference and declaration in this file (and any
headers/tests that refer to these symbols) including uses in functions,
initializations, and any externs so the new identifiers replace the old ones
everywhere to avoid compile errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Tests/Example/ExampleServiceThreadTest.cpp`:
- Around line 19-21: Rename the test globals g_sleepCallCount, g_lastSleepMs,
and g_sleepShutdown to camelCase names (sleepCallCount, lastSleepMs,
sleepShutdown) to comply with project naming rules; update every reference and
declaration in this file (and any headers/tests that refer to these symbols)
including uses in functions, initializations, and any externs so the new
identifiers replace the old ones everywhere to avoid compile errors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a470c75e-e06d-4372-b3cb-f49424f6852f

📥 Commits

Reviewing files that changed from the base of the PR and between 7a2ccfa and 771eeb5.

📒 Files selected for processing (6)
  • DEVLOG.md
  • Example/Common/ExampleServiceThread.c
  • Example/Common/ExampleServiceThread.h
  • Example/Threaded/main.c
  • Example/Windows/SolidSyslogWindowsExample.c
  • Tests/Example/ExampleServiceThreadTest.cpp

@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1091 passed, 🙈 3 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1037 passed, 🙈 3 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1037 passed, 🙈 3 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 100% successful (✔️ 46 passed)
   🚦   bdd-windows-otel: 96% successful (✔️ 44 passed, 🙈 2 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 948 passed, 🙈 1 skipped)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

Project convention is plain camelCase for variables — Hungarian-style
prefixes are forbidden by CLAUDE.md. The g_ prefix was copied from
SolidSyslogTlsStreamTest.cpp, which itself violates the rule;
propagating it was a mistake.
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1091 passed, 🙈 3 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1037 passed, 🙈 3 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1037 passed, 🙈 3 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 100% successful (✔️ 46 passed)
   🚦   bdd-windows-otel: 96% successful (✔️ 44 passed, 🙈 2 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 948 passed, 🙈 1 skipped)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@DavidCozens DavidCozens merged commit cdfa66e into main May 7, 2026
18 checks passed
@DavidCozens DavidCozens deleted the feat/example-service-thread-yield branch May 7, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S12.15: Service thread idle yield

1 participant