{"id":13995308,"url":"https://github.com/oliver-giersch/hazptr","last_synced_at":"2025-08-14T18:32:02.065Z","repository":{"id":62440007,"uuid":"175258800","full_name":"oliver-giersch/hazptr","owner":"oliver-giersch","description":"Hazard pointer based concurrent memory reclamation for Rust.","archived":false,"fork":false,"pushed_at":"2020-04-20T05:58:52.000Z","size":375,"stargazers_count":29,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-11-29T17:38:26.441Z","etag":null,"topics":["hazard-pointer","reclamation","reclamation-schemes","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oliver-giersch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-12T16:56:18.000Z","updated_at":"2024-01-06T20:42:54.000Z","dependencies_parsed_at":"2022-11-01T22:00:44.712Z","dependency_job_id":null,"html_url":"https://github.com/oliver-giersch/hazptr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oliver-giersch%2Fhazptr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oliver-giersch%2Fhazptr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oliver-giersch%2Fhazptr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oliver-giersch%2Fhazptr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oliver-giersch","download_url":"https://codeload.github.com/oliver-giersch/hazptr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229853759,"owners_count":18134663,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["hazard-pointer","reclamation","reclamation-schemes","rust"],"created_at":"2024-08-09T14:03:20.655Z","updated_at":"2024-12-15T17:34:55.576Z","avatar_url":"https://github.com/oliver-giersch.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Hazptr\n\nHazard pointer based concurrent lock-free memory reclamation.\n\n[![Build Status](https://travis-ci.org/oliver-giersch/hazptr.svg?branch=master)](\nhttps://travis-ci.org/oliver-giersch/hazptr)\n[![Latest version](https://img.shields.io/crates/v/hazptr.svg)](https://crates.io/crates/hazptr)\n[![Documentation](https://docs.rs/hazptr/badge.svg)](https://docs.rs/hazptr)\n[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](\nhttps://github.com/oliver-giersch/hazptr)\n[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](\nhttps://www.rust-lang.org)\n\nWhenever a thread reads a value from shared memory it also protects the loaded\nvalue with a globally visible *hazard pointer*.\nAll threads can *retire* shared values that are no longer needed and accessible\nand cache them locally.\nRetired records are reclaimed (dropped and de-allocated) in bulk, but only when\nthey are not or no longer protected by any hazard pointers.\n\n## Usage\n\nAdd this to your `Cargo.toml`\n\n```\n[dependencies]\nhazptr = \"0.2.0\"\n```\n\n## Minimum Supported Rust Version (MSRV)\n\nThe minimum supported Rust version for this crate is 1.36.0.\n\n## Comparison with [crossbeam-epoch](https://crates.io/crates/crossbeam-epoch)\n\nThe hazard pointer reclamation scheme is generally less efficient then\nepoch-based reclamation schemes (or any other type of reclamation scheme for\nthat matter).\nThis is mainly because acquisition of hazard pointers requires an expensive\nmemory fence to be issued after every load from shared memory.\nIt is, however, usually the best scheme in terms of reclamation reliability.\nRetired records are generally reclaimed in a timely manner and reclamation is\nnot affected by contention.\nThese properties can lead to a better memory footprint of applications using\nhazard pointers instead of other reclamation schemes.\nAlso, since hazard pointers only protect individual pointers from reclamation,\nthey can be better suited for protecting individual records for long periods of\ntime.\nEpoch-based schemes, on the other hand, completely prevent reclamation by all\nthreads whenever records need to be protected.\n\n## Examples\n\nSee [examples/treiber/stack.rs](examples/treiber/stack.rs) for an implementation\nof Treiber's stack with hazard pointers or\n[examples/hash_set/ordered.rs](examples/hash_set/ordered/mod.rs) for an\nimplementation of a concurrent hash set.\n\n## Crate Features \u0026 Runtime Configuration\n\nThe following features are defined for this crate:\n\n- `std` (default)\n- `count-release`\n\nBy default, a thread initiates a GC scan and attempts to flush its cache of\nretired records, once it has retired a certain threshold count of records.\nBy compiling the crate with the `count-release` feature, this can be changed to\ncount the instances of successfully acquired hazard pointers `Guard`s going\nout of scope (i.e. being released) instead.\nThis can be beneficial, e.g. when there are only few records overall and\ntheir retirement is rare.\n\n### Scan Threshold\n\nThe scan threshold value is used internally for determining the frequency of\nGC scans.\nThese scans traverse the thread local list of retired records and reclaim all\nrecords which are no longer protected by any hazard pointers.\nThis threshold variable can be any positive non-zero 32-bit integer value and\nis set to 100 by default.\nIt can be set to a different value exactly once during the runtime of the\nprogram.\nNote that only threads that are spawned **after** setting this variable will\nbe able to use the adjusted value.\nThe following code gives an example for how to adjust this value:\n\n```rust\nuse hazptr::{ConfigBuilder, CONFIG};\n\nfn main() {\n    // preferably this should be called before spawning any threads\n    CONFIG.init_once(|| ConfigBuilder::new().scan_threshold(512).build());\n}\n```\n\nA scan threshold of 1 means, for example, that a GC scan is initiated\nafter **every** operation counting towards the threshold, meaning either\noperations for retiring records or releases of `Guard`s, in case the\n`count-release` feature is enabled.\nThe env var can be specified e.g. by invoking `cargo` with:\n\n```\nenv HAZPTR_SCAN_THRESHOLD=1 cargo build\n```\n\nAlternatively, this variable could also be set as part of a build script:\n\n```rust\n// build.rs\n\nfn main() {\n    // alternative: std::env::set_var(\"HAZPTR_SCAN_THRESHOLD\", \"1\")\n    println!(\"cargo:rustc-env=HAZPTR_SCAN_THRESHOLD=1\");\n}\n```\n\nIt is necessary to call `cargo clean`, before attempting to change this variable\nonce set, in order to force a rebuild with the new value.\n\nAs a general rule, a higher scan threshold is better performance-wise, since\nthreads have to attempt to reclaim records less frequently, but could lead to\nthe accumulation of large amounts of garbage and also degrade performance.\n\n### Usage in `#[no_std]` environments\n\nWhen building the crate without the (default) `std` feature, it becomes\npossible to use its functionality in an `#[no_std]` + `alloc` environment, albeit\nwith arguably worse ergonomics.\nIn this configuration, the crate's public API additionally exposes the `Local`\ntype.\nAlso, instead of exporting the `Guard` type, a different `LocalGuard` type is\nexported, which contains an explicit reference to the thread local state.\n\nIn order to use `hazptr` in such an environment, one has to manually to do the\nfollowing steps:\n\n- for every thread, create a separate `Local` instance\n- hazard pointers can only be created by explicitly passing a reference to the\n  current thread's `Local` instance\n\n## License\n\nHazptr is distributed under the terms of both the MIT license and the\nApache License (Version 2.0).\n\nSee [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foliver-giersch%2Fhazptr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foliver-giersch%2Fhazptr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foliver-giersch%2Fhazptr/lists"}