Skip to content

Commit

Permalink
Merge pull request #3 from KDFJW/feature/no-std
Browse files Browse the repository at this point in the history
Support no_std environments
  • Loading branch information
KDFJW committed Mar 23, 2024
2 parents 50fa61c + fa4f0b6 commit c397e8f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 35 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.2.0 - 3/24/24

## Changed
- The library now links against `core` and `alloc` instead of `std`

## 1.1.0 - 3/23/24

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "ptr_cell"
version = "1.1.0"
version = "1.2.0"
authors = ["Nikolay Levkovsky <nik@nous.so>"]
edition = "2021"
description = "Thread-safe cell based on atomic pointers to externally stored data"
readme = "README.md"
repository = "https://github.com/KDFJW/ptr_cell"
license = "CC0-1.0 OR Apache-2.0"
keywords = ["thread-safe", "atomic", "cell"]
categories = ["concurrency", "data-structures", "memory-management"]
keywords = ["thread-safe", "atomic", "cell", "no_std"]
categories = ["memory-management", "data-structures", "concurrency", "no-std"]
49 changes: 26 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Simple thread-safe cell

[`PtrCell`][1] is an atomic cell type that allows safe, concurrent access to shared data. No [data
races][2], no [nasal demons (UB)][3], and most importantly, no [locks][4]
[`PtrCell`][1] is an atomic cell type that allows safe, concurrent access to shared data. No
[`std`][2], no [data races][3], no [nasal demons (UB)][4], and most importantly, no [locks][5]

This type is only useful in scenarios where you need to update a shared value by moving in and out
of it. If you want to concurrently update a value through mutable references, take a look at the
standard [`Mutex`][5] and [`RwLock`][6] instead
of it. If you want to concurrently update a value through mutable references and don't require
support for environments without the standard library ([`no_std`][6]), take a look at the standard
[`Mutex`][7] and [`RwLock`][8] instead

#### Offers:
- **Ease of use**: The API is fairly straightforward
Expand Down Expand Up @@ -52,16 +53,16 @@ assert_eq!(cell.take(), Some(2047))
## Semantics

`PtrCell` allows you to specify memory ordering semantics for its internal atomic operations through
the [`Semantics`][7] enum. Choosing appropriate semantics is crucial for achieving the desired level
the [`Semantics`][9] enum. Choosing appropriate semantics is crucial for achieving the desired level
of synchronization and performance. The available semantics are:

- [`Ordered`][8]: Noticeable overhead, strict
- [`Coupled`][9]: Acceptable overhead, intuitive
- [`Relaxed`][10]: Little overhead, unconstrained
- [`Ordered`][10]: Noticeable overhead, strict
- [`Coupled`][11]: Acceptable overhead, intuitive
- [`Relaxed`][12]: Little overhead, unconstrained

`Coupled` is what you'd typically use. However, other orderings have their use cases too. For
example, the `Relaxed` semantics could be useful when the operations are already ordered through
other means, like [fences][11]. As always, the documentation for each item contains more details
other means, like [fences][13]. As always, the documentation for each item contains more details

## Examples

Expand Down Expand Up @@ -133,23 +134,25 @@ where

## Contributing

Yes, please! See [CONTRIBUTING.md][12]
Yes, please! See [CONTRIBUTING.md][14]

## License

Either CC0 1.0 Universal or the Apache License 2.0. See [LICENSE.md][13] for more details
Either CC0 1.0 Universal or the Apache License 2.0. See [LICENSE.md][15] for more details

<!-- References -->
[1]: https://docs.rs/ptr_cell/latest/ptr_cell/struct.PtrCell.html
[2]: https://en.wikipedia.org/wiki/Race_condition#In_software
[3]: https://en.wikipedia.org/wiki/Undefined_behavior
[4]: https://en.wikipedia.org/wiki/Lock_(computer_science)
[5]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
[6]: https://doc.rust-lang.org/std/sync/struct.RwLock.html
[7]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html
[8]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html#variant.Ordered
[9]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html#variant.Coupled
[10]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html#variant.Relaxed
[11]: https://doc.rust-lang.org/std/sync/atomic/fn.fence.html
[12]: CONTRIBUTING.md
[13]: LICENSE.md
[2]: https://doc.rust-lang.org/std/
[3]: https://en.wikipedia.org/wiki/Race_condition#In_software
[4]: https://en.wikipedia.org/wiki/Undefined_behavior
[5]: https://en.wikipedia.org/wiki/Lock_(computer_science)
[6]: https://docs.rust-embedded.org/book/intro/no-std.html
[7]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
[8]: https://doc.rust-lang.org/std/sync/struct.RwLock.html
[9]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html
[10]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html#variant.Ordered
[11]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html#variant.Coupled
[12]: https://docs.rs/ptr_cell/latest/ptr_cell/enum.Semantics.html#variant.Relaxed
[13]: https://doc.rust-lang.org/std/sync/atomic/fn.fence.html
[14]: CONTRIBUTING.md
[15]: LICENSE.md
23 changes: 15 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! # Simple thread-safe cell
//!
//! [`PtrCell`] is an atomic cell type that allows safe, concurrent access to shared data. No [data
//! races][1], no [nasal demons (UB)][2], and most importantly, no [locks][3]
//!
//! [`PtrCell`] is an atomic cell type that allows safe, concurrent access to shared data. No
//! [`std`], no [data races][1], no [nasal demons (UB)][2], and most importantly, no [locks][3]
//
//! This type is only useful in scenarios where you need to update a shared value by moving in and
//! out of it. If you want to concurrently update a value through mutable references, take a look at
//! out of it. If you want to concurrently update a value through mutable references and don't
//! require support for environments without the standard library ([`no_std`][4]), take a look at
//! the standard [`Mutex`](std::sync::Mutex) and [`RwLock`](std::sync::RwLock) instead
//!
//! #### Offers:
Expand Down Expand Up @@ -117,11 +118,17 @@
//! [1]: https://en.wikipedia.org/wiki/Race_condition#In_software
//! [2]: https://en.wikipedia.org/wiki/Undefined_behavior
//! [3]: https://en.wikipedia.org/wiki/Lock_(computer_science)
//! [4]: https://docs.rust-embedded.org/book/intro/no-std.html

// You WILL use core and you WILL like it
#![no_std]
// You WILL document your code and you WILL like it
#![warn(missing_docs)]

use std::sync::atomic::Ordering;
extern crate alloc;

use alloc::boxed::Box;
use core::sync::atomic::Ordering;

// As far as I can tell, accessing the cell's value is only safe when you have exclusive access to
// the pointer. In other words, either after replacing the pointer, or when working with a &mut or
Expand Down Expand Up @@ -154,7 +161,7 @@ use std::sync::atomic::Ordering;
#[derive(Debug)]
pub struct PtrCell<T> {
/// Pointer to the contained value
value: std::sync::atomic::AtomicPtr<T>,
value: core::sync::atomic::AtomicPtr<T>,
/// Group of memory orderings for internal atomic operations
order: Semantics,
}
Expand Down Expand Up @@ -399,7 +406,7 @@ impl<T> PtrCell<T> {
/// [1]: https://doc.rust-lang.org/std/boxed/index.html#memory-layout
#[inline(always)]
const unsafe fn from_ptr(ptr: *mut T, order: Semantics) -> Self {
let value = std::sync::atomic::AtomicPtr::new(ptr);
let value = core::sync::atomic::AtomicPtr::new(ptr);

Self { value, order }
}
Expand Down Expand Up @@ -452,7 +459,7 @@ impl<T> PtrCell<T> {
#[inline(always)]
fn heap_leak(slot: Option<T>) -> *mut T {
let Some(value) = slot else {
return std::ptr::null_mut();
return core::ptr::null_mut();
};

let allocation = Box::new(value);
Expand Down

0 comments on commit c397e8f

Please sign in to comment.