{"id":22281039,"url":"https://github.com/slide-rs/atom","last_synced_at":"2026-03-04T18:04:05.418Z","repository":{"id":29842847,"uuid":"33387608","full_name":"slide-rs/atom","owner":"slide-rs","description":"Safe atomic pointers","archived":false,"fork":false,"pushed_at":"2021-10-09T09:18:58.000Z","size":115,"stargazers_count":59,"open_issues_count":9,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-03T00:56:31.676Z","etag":null,"topics":["atom","pointer","rust"],"latest_commit_sha":null,"homepage":"","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/slide-rs.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}},"created_at":"2015-04-03T23:31:37.000Z","updated_at":"2025-01-16T23:48:36.000Z","dependencies_parsed_at":"2022-09-07T18:24:50.256Z","dependency_job_id":null,"html_url":"https://github.com/slide-rs/atom","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/slide-rs/atom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slide-rs%2Fatom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slide-rs%2Fatom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slide-rs%2Fatom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slide-rs%2Fatom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slide-rs","download_url":"https://codeload.github.com/slide-rs/atom/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slide-rs%2Fatom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30088346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T15:40:14.053Z","status":"ssl_error","status_checked_at":"2026-03-04T15:40:13.655Z","response_time":59,"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":["atom","pointer","rust"],"created_at":"2024-12-03T16:12:58.159Z","updated_at":"2026-03-04T18:04:05.400Z","avatar_url":"https://github.com/slide-rs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"Atom\n====\n\n`Atom` is a simple abstraction around Rust's `AtomicPtr`. It provides a simple, wait-free way to exchange\ndata between threads safely. `Atom` is built around the principle that an atomic swap can be used to\nsafely emulate Rust's ownership.\n\n![store](assets/store.png)\n\nUsing [`store`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.store) to set a shared\natomic pointer is unsafe in rust (or any language) because the contents of the pointer can be overwritten at any\npoint in time causing the contents of the pointer to be lost. This can cause your system to leak memory, and\nif you are expecting that memory to do something useful (like wake a sleeping thread), you are in trouble.\n\n![load](assets/load.png)\n\nSimilarly, [`load`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.store) \nis unsafe since there is no guarantee that that pointer will live for even a cycle after you have read it. Another\nthread may modify the pointer, or free it. For `load` to be safe you need to have some outside contract to preserve\nthe correct ownership semantics.\n\n![swap](assets/swap.png)\n\nA [`swap`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.swap) is special as it allows\na reference to be exchanged without the risk of that pointer being freed, or stomped on. When a thread\nswaps an `AtomicPtr` the old pointer ownership is moved to the caller, and the `AtomicPtr` takes ownership of the new\npointer.\n\nUsing `Atom`\n------------\n\nAdd atom your `Cargo.toml`\n```\n[dependencies]\natom=\"*\"\n```\n\nA short example:\n```rust\nextern crate atom;\n\nuse std::sync::Arc;\nuse std::thread;\nuse atom::*;\n\nfn main() {\n    // Create an empty atom\n    let shared_atom = Arc::new(Atom::empty());\n\n    // set the value 75 \n    shared_atom.swap(Box::new(75));\n\n    // Spawn a bunch of thread that will try and take the value\n    let threads: Vec\u003cthread::JoinHandle\u003c()\u003e\u003e = (0..8).map(|_| {\n        let shared_atom = shared_atom.clone();\n        thread::spawn(move || {\n            // Take the contents of the atom, only one will win the race\n            if let Some(v) = shared_atom.take() {\n                println!(\"I got it: {:?} :D\", v);\n            } else {\n                println!(\"I did not get it :(\");\n            }\n        })\n    }).collect();\n\n    // join the threads\n    for t in threads { t.join().unwrap(); }\n\n```\n\nThe result will look something like this:\n```\nI did not get it :(\nI got it: 75 :D\nI did not get it :(\nI did not get it :(\nI did not get it :(\nI did not get it :(\nI did not get it :(\nI did not get it :(\n```\n\nUsing an `Atom` has some advantages over using a raw `AtomicPtr`. First, you don't need any\nunsafe code in order to convert the `Box\u003cT\u003e` to and from a `Box` the library handles that for\nyou. Secondly, `Atom` implements `drop` so you won't accidentally leak a pointer when dropping\nyour data structure.\n\nAtomSetOnce\n-----------\n\nThis is an additional bit of abstraction around an Atom. Recall that I said `load` was unsafe\nunless you have an additional restrictions. `AtomSetOnce` as the name indicates may only be\nset once, and then it may never be unset. We know that if the `Atom` is set the pointer will be\nvalid for the lifetime of the `Atom`. This means we can implement `Deref` in a safe way.\n\nTake a look at the `fifo` example to see how this can be used to write a lock-free linked list.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslide-rs%2Fatom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslide-rs%2Fatom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslide-rs%2Fatom/lists"}