{"id":15031045,"url":"https://github.com/pedromfedricci/clhlock","last_synced_at":"2026-02-25T11:01:41.916Z","repository":{"id":255119186,"uuid":"848578681","full_name":"pedromfedricci/clhlock","owner":"pedromfedricci","description":"An implementation of Craig and, indenpendently, Magnussen, Landin, and Hagersten queue lock for mutual exclusion, referred to as CLH lock.","archived":false,"fork":false,"pushed_at":"2025-04-29T20:19:11.000Z","size":139,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-29T21:22:41.703Z","etag":null,"topics":["concurrency","multithreading","mutex","mutual-exclusion","rust-lang","spinlock","synchronization"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/clhlock","language":"Rust","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/pedromfedricci.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","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}},"created_at":"2024-08-28T02:46:17.000Z","updated_at":"2025-02-13T03:13:49.000Z","dependencies_parsed_at":"2025-01-20T20:23:23.491Z","dependency_job_id":"feb76531-5104-46dc-9ff9-00f3169a7782","html_url":"https://github.com/pedromfedricci/clhlock","commit_stats":{"total_commits":20,"total_committers":1,"mean_commits":20.0,"dds":0.0,"last_synced_commit":"7eb23b26e9159450253f5a86d7e3d85298f406d6"},"previous_names":["pedromfedricci/clhlock"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/pedromfedricci/clhlock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromfedricci%2Fclhlock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromfedricci%2Fclhlock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromfedricci%2Fclhlock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromfedricci%2Fclhlock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedromfedricci","download_url":"https://codeload.github.com/pedromfedricci/clhlock/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromfedricci%2Fclhlock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29819265,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-25T05:36:42.804Z","status":"ssl_error","status_checked_at":"2026-02-25T05:36:31.934Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["concurrency","multithreading","mutex","mutual-exclusion","rust-lang","spinlock","synchronization"],"created_at":"2024-09-24T20:14:47.242Z","updated_at":"2026-02-25T11:01:41.874Z","avatar_url":"https://github.com/pedromfedricci.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A simple and correct implementation of the CLH lock\n\n[![MIT][mit-badge]][mit]\n[![Apache 2.0][apache2-badge]][apache2]\n[![Crates][crates-badge]][crates]\n[![Docs][docs-badge]][docs]\n[![CI][ci-badge]][ci]\n[![Codecov][codecov-badge]][codecov]\n![No_std][no_std-badge]\n\nCLH lock is a List-Based Queuing Lock that avoids network contention by\nhaving threads spin and on locally accessible memory locations. The main\nproperties of this mechanism are:\n\n- guarantees FIFO ordering of lock acquisitions;\n- spins on locally-accessible flag variables only;\n- requires a small constant amount of space per lock; and\n- works equally well (requiring only O(1) network transactions per lock\n  acquisition) on machines with and without coherent caches.\n- avoids the \"handshake\" runtime overhead between the lock holder and\n  its successor during lock hand-off.\n\nThis algorithm was indenpendently introduced by [Craig] and\n[Magnussen, Landin, and Hagersten] papers.\n\n## Spinlock use cases\n\nIt is noteworthy to mention that [spinlocks are usually not what you want].\nThe majority of use cases are well covered by OS-based mutexes like\n[`std::sync::Mutex`], [`parking_lot::Mutex`]. These implementations will\nnotify the system that the waiting thread should be parked, freeing the\nprocessor to work on something else.\n\nSpinlocks are only efficient in very few circunstances where the overhead\nof context switching or process rescheduling are greater than busy waiting\nfor very short periods. Spinlocks can be useful inside operating-system\nkernels, on embedded systems or even complement other locking designs.\n\n## Install\n\nRun the following Cargo command in your project directory:\n\n```bash\ncargo add clhlock\n```\n\nOr add a entry under the `[dependencies]` section in your `Cargo.toml`:\n\n```toml\n# Cargo.toml\n\n[dependencies]\n# Features: `yield`.\nclhlock = { version = \"0.2\", features = [\"yield\"] }\n```\n\n## Documentation\n\nThis project documentation is hosted at [docs.rs][docs]. Or you can build it\nlocally with the following command:\n\n```bash\nRUSTDOCFLAGS=\"--cfg docsrs\" cargo +nightly doc --all-features --open\n```\n\n## Waiting queue node allocations\n\nQueue nodes are allocated in the heap, and their ownership is transparently\nmoved from the lock holding thread to its successor. Allocating the nodes\ndirectly in the stack is not possible since the CLH lock protocol does not\nguarantee that a predecessor thread will be live by the time a successor access\nits associated locking node. Locking operations require taking ownership over\nnode handles that manage the heap allocations. Node handles are represented \nby the [`raw::MutexNode`] type. Therefore, this crate requires linking with\nRust's core [alloc] library.\n\n## Locking with a raw CLH spinlock\n\nThis implementation operates under FIFO. Raw locking APIs require taking\nownership over node handles that manage the heap allocated queue nodes. These\nnode handles are represented by the [`raw::MutexNode`] type. This implementation\nis `no_std` compatible. See the [`raw`] module for more information.\n\n```rust\nuse std::sync::Arc;\nuse std::thread;\n\n// Simply spins during contention.\nuse clhlock::raw::{spins::Mutex, MutexNode};\n\nfn main() {\n    let mutex = Arc::new(Mutex::new(0));\n    let c_mutex = Arc::clone(\u0026mutex);\n\n    thread::spawn(move || {\n        // A handle to a heap allocated queue node.\n        let node = MutexNode::new();\n        // The queue node handle must be consumed.\n        *c_mutex.lock_with(node) = 10;\n    })\n    .join().expect(\"thread::spawn failed\");\n\n    // A node may also be transparently allocated.\n    assert_eq!(*mutex.lock(), 10);\n}\n```\n\n## Features\n\nThis crate dos not provide any default features. Features that can be enabled\nare:\n\n### yield\n\nThe `yield` feature requires linking to the standard library, so it is not\nsuitable for `no_std` environments. By enabling the `yield` feature, instead\nof busy-waiting during lock acquisitions and releases, this will call\n[`std::thread::yield_now`], which cooperatively gives up a timeslice to the\nOS scheduler. This may cause a context switch, so you may not want to enable\nthis feature if your intention is to to actually do optimistic spinning. The\ndefault implementation calls [`core::hint::spin_loop`], which does in fact\njust simply busy-waits. This feature is not `not_std` compatible.\n\n## Minimum Supported Rust Version (MSRV)\n\nThis crate is guaranteed to compile on a Minimum Supported Rust Version (MSRV)\nof 1.65.0 and above. This version will not be changed without a minor version\nbump.\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or \u003chttp://apache.org/licenses/LICENSE-2.0\u003e)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or \u003chttp://opensource.org/licenses/MIT\u003e)\n\n## Contributing\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n\n## Code review\n\nIt is recommended to always use [cargo-crev] to verify the trustworthiness of\neach of your dependencies, including this one.\n\n[mit-badge]: https://img.shields.io/badge/License-MIT-blue.svg\n[apache2-badge]: https://img.shields.io/badge/License-Apache_2.0-yellow.svg\n[docs-badge]: https://img.shields.io/docsrs/clhlock\n[crates-badge]: https://img.shields.io/crates/v/clhlock\n[ci-badge]: https://github.com/pedromfedricci/clhlock/actions/workflows/ci.yml/badge.svg\n[codecov-badge]: https://codecov.io/gh/pedromfedricci/clhlock/graph/badge.svg?token=A54PAF1K74\n[no_std-badge]: https://img.shields.io/badge/no__std-compatible-success.svg\n\n[mit]: https://opensource.org/licenses/MIT\n[apache2]: https://opensource.org/licenses/Apache-2.0\n[docs]: https://docs.rs/clhlock\n[crates]: https://crates.io/crates/clhlock\n[ci]: https://github.com/pedromfedricci/clhlock/actions/workflows/ci.yml\n[codecov]: https://codecov.io/gh/pedromfedricci/clhlock\n[cargo-crev]: https://github.com/crev-dev/cargo-crev\n\n[Craig]: https://dada.cs.washington.edu/research/tr/1993/02/UW-CSE-93-02-02.pdf\n[Magnussen, Landin, and Hagersten]: https://www2.it.uu.se/research/group/uart/pub/magnusson_1994_jan/magnusson_1994_jan.pdf\n[spinlocks are usually not what you want]: https://matklad.github.io/2020/01/02/spinlocks-considered-harmful.html\n\n[`raw`]: https://docs.rs/clhlock/latest/clhlock/raw/index.html\n[`raw::Mutex`]: https://docs.rs/clhlock/latest/clhlock/raw/struct.Mutex.html\n[`raw::MutexNode`]: https://docs.rs/clhlock/latest/clhlock/raw/struct.MutexNode.html\n\n[alloc]: https://doc.rust-lang.org/alloc/index.html\n[`std::sync::Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html\n[`std::thread::yield_now`]: https://doc.rust-lang.org/std/thread/fn.yield_now.html\n[`core::hint::spin_loop`]: https://doc.rust-lang.org/core/hint/fn.spin_loop.html\n\n[`parking_lot::Mutex`]: https://docs.rs/parking_lot/latest/parking_lot/type.Mutex.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedromfedricci%2Fclhlock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedromfedricci%2Fclhlock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedromfedricci%2Fclhlock/lists"}