{"id":49594757,"url":"https://github.com/timo-kang/lock-free-ring-buffer","last_synced_at":"2026-05-04T03:10:59.904Z","repository":{"id":336809469,"uuid":"1151202238","full_name":"timo-kang/lock-free-ring-buffer","owner":"timo-kang","description":"Lock Free Ringbuffer implementaion for shared-memory messaging","archived":false,"fork":false,"pushed_at":"2026-04-27T05:02:08.000Z","size":152,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-27T07:06:45.342Z","etag":null,"topics":["lock-free","mpmc","spsc"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timo-kang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-06T07:06:53.000Z","updated_at":"2026-04-27T05:02:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/timo-kang/lock-free-ring-buffer","commit_stats":null,"previous_names":["timo-kang/lock-free-ring-buffer"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/timo-kang/lock-free-ring-buffer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timo-kang%2Flock-free-ring-buffer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timo-kang%2Flock-free-ring-buffer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timo-kang%2Flock-free-ring-buffer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timo-kang%2Flock-free-ring-buffer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timo-kang","download_url":"https://codeload.github.com/timo-kang/lock-free-ring-buffer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timo-kang%2Flock-free-ring-buffer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32592746,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T22:12:39.696Z","status":"online","status_checked_at":"2026-05-04T02:00:06.625Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lock-free","mpmc","spsc"],"created_at":"2026-05-04T03:10:59.105Z","updated_at":"2026-05-04T03:10:59.898Z","avatar_url":"https://github.com/timo-kang.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lock-free-ring-buf\n\nA C++20 lock-free ring buffer for shared-memory messaging. It supports **MPSC** and **MPMC** (multi‑producer, multi‑consumer) with variable‑size payloads and a memory‑mapped file backend. It is designed to minimize false sharing with cache‑line padded control fields.\n\n## Features\n- MPSC lock-free ring buffer (shared memory via `mmap`).\n- MPMC lock-free ring buffer (shared memory via `mmap`).\n- `SharedLatest\u003cT\u003e` seqlock-style \"latest value\" for SWMR (single writer, many readers).\n- Variable-size payloads with a small record header (`size`, `type`, `flags`).\n- Global monotonic sequence number per record (for loss detection / diagnostics).\n- Cache-line padded control block to reduce false sharing.\n- Unit tests (GoogleTest) and benchmarks (Google Benchmark).\n\n## Status / Roadmap\n- MPMC support: **implemented** (separate class).\n- Typed message helpers / serialization helpers: **implemented**.\n- SPSC FIFO (dedicated implementation): **implemented** (`SPSCQueue\u003cT, Capacity\u003e`).\n- Windows shared-memory backend: **planned**.\n\n## Build\n```bash\ncmake -S . -B build\ncmake --build build\n```\n\n## Usage (MPSC)\n```cpp\n#include \"lf_ring/shared_ring_buffer.hpp\"\n#include \u003ccstdint\u003e\n#include \u003cvector\u003e\n\nint main() {\n  auto ring = lfring::SharedRingBuffer::create(\"/tmp/lfring.bin\", 1 \u003c\u003c 20);\n\n  const char payload[] = \"hello\";\n  ring.try_push(payload, sizeof(payload), /*type=*/1);\n\n  std::vector\u003cstd::byte\u003e out;\n  std::uint16_t type = 0;\n  if (ring.try_pop(out, type)) {\n    // process message\n  }\n}\n```\n\n## Usage (MPMC)\n```cpp\n#include \"lf_ring/shared_ring_buffer_mpmc.hpp\"\n#include \u003ccstdint\u003e\n#include \u003cvector\u003e\n\nint main() {\n  auto ring = lfring::SharedRingBufferMPMC::create(\"/tmp/lfring_mpmc.bin\", 1 \u003c\u003c 20);\n\n  const char payload[] = \"hello\";\n  ring.try_push(payload, sizeof(payload), /*type=*/1);\n\n  std::vector\u003cstd::byte\u003e out;\n  std::uint16_t type = 0;\n  if (ring.try_pop(out, type)) {\n    // process message\n  }\n}\n```\n\n## Typed Messages\nTyped helpers wrap the raw byte API. Define a message type ID and use the writer/reader:\n```cpp\n#include \"lf_ring/shared_ring_buffer.hpp\"\n#include \"lf_ring/typed_message.hpp\"\n\nstruct PriceUpdate {\n  uint32_t id;\n  double price;\n};\n\nnamespace lfring {\ntemplate \u003c\u003e\nstruct MessageType\u003cPriceUpdate\u003e {\n  static constexpr bool defined = true;\n  static constexpr uint16_t value = 42;\n};\n} // namespace lfring\n\nint main() {\n  auto ring = lfring::SharedRingBuffer::create(\"/tmp/lfring.bin\", 1 \u003c\u003c 20);\n  lfring::TypedMessageWriter\u003clfring::SharedRingBuffer\u003e writer(ring);\n  lfring::TypedMessageReader\u003clfring::SharedRingBuffer\u003e reader(ring);\n\n  writer.try_push(PriceUpdate{7, 99.5});\n\n  PriceUpdate out{};\n  reader.try_pop(out);\n}\n```\n\n## SPSC Queue (SPSCQueue)\nA fixed-size, typed single-producer single-consumer queue backed by shared memory:\n```cpp\n#include \"lf_ring/spsc_queue.hpp\"\n\nint main() {\n  auto q = lfring::SPSCQueue\u003cstd::uint64_t, 1024\u003e::create(\"/tmp/spsc.bin\");\n\n  q.try_push(42u);\n\n  std::uint64_t out = 0;\n  if (q.try_pop(out)) {\n    // out == 42\n  }\n}\n```\n\n## Latest-Value Topics (SharedLatest)\nFor robotics style \"state/latest\" topics (robot state, telemetry, latest command), FIFO is often the wrong semantic.\n`SharedLatest\u003cT\u003e` provides SWMR latest-value semantics with a seqlock-style counter so readers do not observe torn reads.\n\nThe `ReadResult` overload of `try_read` can detect writer death — if the writer process dies mid-write, readers get `kWriterDead` instead of silently spinning:\n```cpp\n#include \"lf_ring/shared_latest.hpp\"\nusing namespace std::chrono_literals;\n\nstruct RobotState {\n  double x;\n  double y;\n  double yaw;\n  uint64_t stamp_ns;\n};\n\nint main() {\n  auto latest = lfring::SharedLatest\u003cRobotState\u003e::create(\"/tmp/robot_state.bin\");\n  latest.write(RobotState{1.0, 2.0, 0.5, 123});\n\n  RobotState out{};\n\n  // Simple read (backward compatible):\n  if (latest.try_read(out)) {\n    // out is a consistent snapshot\n  }\n\n  // Rich-status read with writer-death detection:\n  auto result = latest.try_read(out, /*dead_threshold=*/100ms);\n  switch (result) {\n    case lfring::ReadResult::kSuccess:    /* consistent snapshot */ break;\n    case lfring::ReadResult::kEmpty:      /* no data written yet */ break;\n    case lfring::ReadResult::kContended:  /* writer is mid-write, still alive */ break;\n    case lfring::ReadResult::kWriterDead: /* writer died mid-write */ break;\n  }\n\n  // Check liveness independently:\n  if (!latest.is_writer_alive(100ms)) {\n    // writer hasn't written in 100ms\n  }\n}\n```\n\n## Tests\n```bash\nctest --test-dir build\n```\n\n## Benchmarks\n```bash\n./build/lf_ring_bench --benchmark_format=console\n```\n\n## Notes\n- Linux/POSIX backend only (`mmap`, `open`, `ftruncate`).\n- Requires lock‑free 64‑bit atomics.\n- MPSC only: a single consumer thread/process must call `try_pop`.\n- SharedLatest is SWMR only (one writer; many readers). Use the `ReadResult` overload of `try_read` to detect writer death via heartbeat checking.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimo-kang%2Flock-free-ring-buffer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimo-kang%2Flock-free-ring-buffer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimo-kang%2Flock-free-ring-buffer/lists"}