{"id":50988379,"url":"https://github.com/cong-or/snarf","last_synced_at":"2026-07-07T22:00:30.650Z","repository":{"id":358056574,"uuid":"1229031283","full_name":"cong-or/snarf","owner":"cong-or","description":" Cache-line false sharing linter for Rust structs","archived":false,"fork":false,"pushed_at":"2026-05-25T14:48:44.000Z","size":642,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T16:33:58.438Z","etag":null,"topics":["cache-line","ci","concurrency","false-sharing","linter","mesi","no-std","performance","rust","static-analysis"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cong-or.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-05-04T16:19:50.000Z","updated_at":"2026-05-25T16:30:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cong-or/snarf","commit_stats":null,"previous_names":["cong-or/snarf"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/cong-or/snarf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cong-or%2Fsnarf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cong-or%2Fsnarf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cong-or%2Fsnarf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cong-or%2Fsnarf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cong-or","download_url":"https://codeload.github.com/cong-or/snarf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cong-or%2Fsnarf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35243953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"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":["cache-line","ci","concurrency","false-sharing","linter","mesi","no-std","performance","rust","static-analysis"],"created_at":"2026-06-19T23:00:38.172Z","updated_at":"2026-07-07T22:00:30.637Z","avatar_url":"https://github.com/cong-or.png","language":"Rust","funding_links":[],"categories":["Linters"],"sub_categories":[],"readme":"# snarf\r\n\r\nCache-line false sharing linter for Rust structs.\r\n\r\n![snarf demo](assets/demo.gif)\r\n\r\n---\r\n\r\nFinds Rust structs where atomic or contended fields share a cache line with other fields. This is potential false sharing, not proven — snarf detects the layout but not runtime behavior, so you decide which fields are actually contended.\r\n\r\n[The Slowdown That Doesn't Show Up in Profiles](https://cong-or.xyz/false-sharing-cache-lines.html) — why this matters.\r\n\r\n---\r\n\r\n### Install and run\r\n\r\n```\r\ncargo install cargo-snarf\r\ncargo snarf\r\n```\r\n\r\nNo output means no issues found. If snarf finds contended fields sharing a cache line, it prints a layout diagram and exits non-zero. In a workspace it discovers all crates automatically.\r\n\r\nsnarf requires nightly Rust to get exact type sizes via `cargo +nightly build -Zprint-type-sizes`. Install it:\r\n\r\n```\r\nrustup toolchain install nightly\r\n```\r\n\r\n### CI\r\n\r\n```yaml\r\n- name: Cache-line sanity check\r\n  run: |\r\n    rustup toolchain install nightly --profile minimal\r\n    cargo install cargo-snarf \u0026\u0026 cargo snarf\r\n```\r\n\r\nFor PR annotations without blocking:\r\n\r\n```yaml\r\n- name: Cache-line annotations\r\n  run: |\r\n    rustup toolchain install nightly --profile minimal\r\n    cargo install cargo-snarf \u0026\u0026 cargo snarf --format github --warn-only\r\n```\r\n\r\nThis repo runs snarf on itself — see [ci.yml](.github/workflows/ci.yml).\r\n\r\n### Options\r\n\r\n| Flag | What it does |\r\n|------|-------------|\r\n| `--strict` | Warn on all multi-field cache lines, not just contended ones |\r\n| `--format json` | Machine-readable output |\r\n| `--format github` | GitHub Actions annotations on the PR diff |\r\n| `--warn-only` | Report issues but exit 0 |\r\n| `--threshold N` | Minimum fields per line to warn (default: 2) |\r\n| `--line-size N` | Cache line size in bytes (default: 64, use 128 for Apple M-series) |\r\n| `--no-send-sync-check` | Warn even on `!Send`/`!Sync` structs (see below) |\r\n| `--color never` | No ANSI escape codes |\r\n\r\nBy default snarf only warns when an `Atomic*`/`Cell`/`RefCell`/`UnsafeCell` field shares a cache line with other fields. Detection is recursive, so `Option\u003cAtomicU64\u003e` and `Arc\u003cMutex\u003cAtomicU64\u003e\u003e` are both caught. `--strict` warns on all multi-field lines regardless.\r\n\r\nStructs containing `!Send` or `!Sync` types (`Rc`, `Cell`, `RefCell`, raw pointers, lock guards) are automatically suppressed since they can't be shared across threads, making false sharing impossible. Suppressed structs print a note to stderr. Use `--no-send-sync-check` to disable this and warn on all structs.\r\n\r\n---\r\n\r\n### How it works\r\n\r\nParses structs with `syn`, then gets exact type sizes and field offsets from `cargo +nightly build -Zprint-type-sizes`. This resolves all types (custom structs, enums, non-repr(C) layouts, niche-optimized `Option`s) with no guessing.\r\n\r\n- All types resolved, including custom and cross-crate types\r\n- Non-repr(C) structs get exact field offsets from the compiler\r\n- Niche optimization (`Option\u003c\u0026T\u003e`, `Option\u003cNonZeroU64\u003e`) handled correctly\r\n\r\n### Validation\r\n\r\nThe `validation/` directory has a controlled experiment that correlates snarf's static warnings with real hardware cache-line contention measured by `perf c2c`. Two `#[repr(C)]` structs (one with co-located atomics, one with cache-line padding) are hammered from threads pinned to separate P-cores. The script runs snarf and `perf c2c`, then compares HITM event counts to snarf's warnings.\r\n\r\n```\r\ncd validation \u0026\u0026 ./run.sh   # requires sudo for perf c2c\r\n```\r\n\r\n### Limitations\r\n\r\n- `repr(packed)` not yet supported\r\n- Type name collisions: if two modules define a type with the same name (e.g. `a::Config` and `b::Config`), only the first is used (a warning is printed)\r\n\r\n### Name\r\n\r\n[snarf](http://www.catb.org/jargon/html/S/snarf.html) — hacker slang: to grab data greedily.\r\n\r\n### License\r\n\r\nMIT\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcong-or%2Fsnarf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcong-or%2Fsnarf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcong-or%2Fsnarf/lists"}