Skip to content

Commit

Permalink
Add portable_atomic for atomics support
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Aschmann committed Mar 24, 2023
1 parent 3b057d3 commit c7df4f1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ c2rust-bitfields = { version = "0.3", features = ["no_std"] }
riot-build = { version = "< 0.2.0", optional = true }
riot-rs-core = { version = "< 0.2.0", optional = true }

# atomic support
portable-atomic = {version = "1.0.1", features = ["critical-section"]}
critical-section = {version = "1.1.1", features = ["restore-state-bool"], optional = true}

[build-dependencies]
bindgen = "^0.60.1"
shlex = "^1"
Expand Down
38 changes: 38 additions & 0 deletions src/critical_section.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//! [`critical_section`] implementation for **single core cpu boards**
//! using RIOTs interrupts interface. (Just disables interrupts).
//!
//! This is needed by [`portable_atomic`] to provide atomics to boards without hardware
//! support or rather where rust does not support atomics.
use critical_section::RawRestoreState;

struct RIOTCriticalSection;

critical_section::set_impl!(RIOTCriticalSection);

unsafe impl critical_section::Impl for RIOTCriticalSection {
unsafe fn acquire() -> RawRestoreState {
if crate::irq_is_in() {
return false;
}

let disabled = crate::irq_is_enabled();
// It is possible that between here an interrupt
// interferes and causes another thread/process to continue.
// This should not be a problem because:
// Szenario 1: The other process does not enter a critical section
// or disables interrupts and nothing happens.
// Szenario 2: The other process does disable interrupts, but
// then this thread here can only continue once the interrupts are back on
// and one causes this thread to continue.
// In both cases we should not face a toctu problem.
crate::irq_disable();
disabled
}

unsafe fn release(token: RawRestoreState) {
if token {
crate::irq_enable();
}
}
}
2 changes: 1 addition & 1 deletion src/intrinsics_replacements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! (But then again, they're not needed, as theire RIOT C code can't contain these operations).
#[cfg(target_arch = "riscv32")]
use core::sync::atomic::{AtomicU32, Ordering};
use portable_atomic::{AtomicU32, Ordering};

#[cfg(target_arch = "riscv32")]
pub(crate) fn atomic_and_relaxed(dst: *mut u32, src: u32) -> u32 {
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ pub mod libc;

mod intrinsics_replacements;

mod critical_section;

mod bindgen;
pub mod inline;

Expand Down

0 comments on commit c7df4f1

Please sign in to comment.