Skip to content

Commit fe6eb8b

Browse files
authored
Merge pull request tock#4551 from tock/single-thread-value-atomics
kernel: add `SingleThreadValue` type for `!Sync` statics, using atomics for synchronization
2 parents c172710 + 1f082be commit fe6eb8b

37 files changed

Lines changed: 879 additions & 8 deletions

File tree

arch/cortex-m/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod scb;
1616
pub mod support;
1717
pub mod syscall;
1818
pub mod systick;
19+
pub mod thread_id;
1920

2021
// These constants are defined in the linker script.
2122
extern "C" {

arch/cortex-m/src/support.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,34 @@ pub fn reset() -> ! {
7474
nop();
7575
}
7676
}
77+
78+
/// Check if we are executing in an interrupt handler or not.
79+
///
80+
/// Returns `true` if the CPU is executing in an interrupt handler. Returns
81+
/// `false` if the chip is executing in thread mode.
82+
#[cfg(any(doc, all(target_arch = "arm", target_os = "none")))]
83+
pub fn is_interrupt_context() -> bool {
84+
use core::arch::asm;
85+
let mut interrupt_number: u32;
86+
87+
// # Safety
88+
//
89+
// This only reads a register and has no effects.
90+
unsafe {
91+
// IPSR[8:0] holds the currently active interrupt
92+
asm!(
93+
"mrs r0, ipsr",
94+
out("r0") interrupt_number,
95+
options(nomem, nostack, preserves_flags)
96+
);
97+
}
98+
99+
// If IPSR[8:0] is 0 then we are in thread mode. Otherwise an interrupt has
100+
// occurred and we are in some interrupt service routine.
101+
(interrupt_number & 0x1FF) != 0
102+
}
103+
104+
#[cfg(not(any(doc, all(target_arch = "arm", target_os = "none"))))]
105+
pub fn is_interrupt_context() -> bool {
106+
unimplemented!()
107+
}

arch/cortex-m/src/thread_id.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed under the Apache License, Version 2.0 or the MIT License.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// Copyright Tock Contributors 2025.
4+
5+
//! Basic implementation of a thread ID provider for Cortex-M.
6+
7+
use kernel::platform::chip::ThreadIdProvider;
8+
9+
/// Implement the [`ThreadIdProvider`] trait for Cortex-M platforms.
10+
///
11+
/// We assign thread IDs this way:
12+
///
13+
/// - 0: Main thread
14+
/// - 1: Any interrupt service routine
15+
pub enum CortexMThreadIdProvider {}
16+
17+
// # Safety
18+
//
19+
// By implementing [`ThreadIdProvider`] we are guaranteeing that we correctly
20+
// return the thread ID. On single-core platforms the thread ID only depends on
21+
// whether execution is in an interrupt service routine or not, which is what
22+
// this implementation checks for.
23+
unsafe impl ThreadIdProvider for CortexMThreadIdProvider {
24+
fn running_thread_id() -> usize {
25+
crate::support::is_interrupt_context() as usize
26+
}
27+
}

arch/cortex-m0/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub use cortexm::support;
1414

1515
pub use cortexm::nvic;
1616
pub use cortexm::syscall;
17+
pub use cortexm::thread_id;
1718

1819
#[cfg(any(doc, all(target_arch = "arm", target_os = "none")))]
1920
struct HardFaultStackedRegisters {

arch/cortex-m0p/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub use cortexm::interrupt_mask;
3030
pub use cortexm::nvic;
3131
pub use cortexm::scb;
3232
pub use cortexm::systick;
33+
pub use cortexm::thread_id;
3334
pub use cortexm::unhandled_interrupt;
3435
pub use cortexm::CortexMVariant;
3536
use cortexm0::CortexM0;

arch/cortex-m3/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub use cortexm::nvic;
2727
pub use cortexm::scb;
2828
pub use cortexm::support;
2929
pub use cortexm::systick;
30+
pub use cortexm::thread_id;
3031
pub use cortexm::unhandled_interrupt;
3132
pub use cortexm::CortexMVariant;
3233

arch/cortex-m33/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub use cortexm::nvic;
3131
pub use cortexm::scb;
3232
pub use cortexm::support;
3333
pub use cortexm::systick;
34+
pub use cortexm::thread_id;
3435
pub use cortexm::unhandled_interrupt;
3536
pub use cortexm::CortexMVariant;
3637

arch/cortex-m4/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub use cortexm::nvic;
2727
pub use cortexm::scb;
2828
pub use cortexm::support;
2929
pub use cortexm::systick;
30+
pub use cortexm::thread_id;
3031
pub use cortexm::unhandled_interrupt;
3132
pub use cortexm::CortexMVariant;
3233

arch/cortex-m4f/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub use cortexm::nvic;
2727
pub use cortexm::scb;
2828
pub use cortexm::support;
2929
pub use cortexm::systick;
30+
pub use cortexm::thread_id;
3031
pub use cortexm::unhandled_interrupt;
3132
pub use cortexm::CortexMVariant;
3233

arch/cortex-m7/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub use cortexm::nvic;
2626
pub use cortexm::scb;
2727
pub use cortexm::support;
2828
pub use cortexm::systick;
29+
pub use cortexm::thread_id;
2930
pub use cortexm::unhandled_interrupt;
3031
pub use cortexm::CortexMVariant;
3132

0 commit comments

Comments
 (0)