Skip to content

Commit a3cdfd8

Browse files
committed
Remove all built-in implementations.
1 parent 88ba991 commit a3cdfd8

File tree

7 files changed

+46
-219
lines changed

7 files changed

+46
-219
lines changed

.vscode/settings.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"editor.formatOnSave": true,
33
"rust-analyzer.procMacro.enable": true,
4-
"rust-analyzer.cargo.loadOutDirsFromCheck": true,
5-
"rust-analyzer.assist.importMergeBehavior": "last"
4+
"rust-analyzer.cargo.runBuildScripts": true,
5+
"rust-analyzer.assist.importGranularity": "module",
66
}

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
No unreleased changes yet
10+
- Breaking change: removed all builtin impls. These are going to be provided by platform-support now.
1111

1212
## 0.2.7 - 2022-04-08
1313

Cargo.toml

+2-25
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
[package]
22
name = "critical-section"
3-
version = "0.2.7"
4-
authors = ["Dario Nieuwenhuis <[email protected]>"]
3+
version = "0.3.0"
54
edition = "2018"
6-
description = "Critical section abstraction"
5+
description = "Cross-platform critical section"
76
repository = "https://github.com/embassy-rs/critical-section"
87
readme = "README.md"
98
license = "MIT OR Apache-2.0"
@@ -13,30 +12,8 @@ categories = [
1312
"concurrency",
1413
]
1514

16-
[features]
17-
custom-impl = []
18-
1915
[dependencies]
2016
bare-metal = "1.0.0"
21-
cfg-if = "1.0.0"
22-
23-
[target.thumbv6m-none-eabi.dependencies]
24-
cortex-m = "0.7.2"
25-
[target.thumbv7em-none-eabi.dependencies]
26-
cortex-m = "0.7.2"
27-
[target.thumbv7em-none-eabihf.dependencies]
28-
cortex-m = "0.7.2"
29-
[target.thumbv7m-none-eabi.dependencies]
30-
cortex-m = "0.7.2"
31-
[target."thumbv8m.base-none-eabi".dependencies]
32-
cortex-m = "0.7.2"
33-
[target."thumbv8m.main-none-eabi".dependencies]
34-
cortex-m = "0.7.2"
35-
[target."thumbv8m.main-none-eabihf".dependencies]
36-
cortex-m = "0.7.2"
37-
38-
[target.'cfg(target_arch = "riscv32")'.dependencies]
39-
riscv = {version = "0.7.0"}
4017

4118
[package.metadata.docs.rs]
4219
all-features = true

README.md

+5-19
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ targets that don't support them, etc.
1212

1313
There's a wide range of possible implementations depending on the execution environment:
1414
- For bare-metal single core, disabling interrupts globally.
15-
- For bare-metal multicore, acquiring a hardware spinlocks and disabling interrupts globally.
15+
- For bare-metal multicore, acquiring a hardware spinlock and disabling interrupts globally.
1616
- For bare-metal using a RTOS, it usually provides library functions for acquiring a critical section, often named "scheduler lock" or "kernel lock".
1717
- For bare-metal running in non-privileged mode, usually some system call is needed.
1818
- For `std` targets, acquiring a global `std::sync::Mutex`.
@@ -26,27 +26,13 @@ could be cases 1-4 from the above list.
2626
This crate solves the problem by providing this missing universal API.
2727

2828
- It provides functions `acquire`, `release` and `free` that libraries can directly use.
29-
- It provides some built-in impls for well-known targets, so in many cases it Just Works.
30-
- It provides a way for any crate to supply a "custom impl" that overrides the built-in one. This allows environment-support crates such as RTOS bindings or HALs for multicore chips to supply the correct impl so that all the crates in the dependency tree automatically use it.
29+
- It provides a way for any crate to supply an implementation. This allows "target support" crates such as architecture crates (`cortex-m`, `riscv`), RTOS bindings, or HALs for multicore chips to supply the correct impl so that all the crates in the dependency tree automatically use it.
3130

32-
## Built-in impls
33-
34-
35-
| Target | Mechanism | Notes |
36-
|--------------------|---------------------------|-------------------|
37-
| thumbv[6-8] | `cpsid` / `cpsie`. | Only sound in single-core privileged mode. |
38-
| riscv32* | set/clear `mstatus.mie` | Only sound in single-core privileged mode. |
39-
| avr* | `cli` / `sei` | Only sound in single-core (does multicore AVR even exist?) |
40-
| std targets | Global `std::sync::Mutex` | |
41-
42-
## Providing a custom impl
43-
44-
- Enable the Cargo feature `custom-impl` in the `critical-section` crate.
45-
- Define it like the following:
31+
## Providing an implementation
4632

4733
```rust
4834
struct CriticalSection;
49-
critical_section::custom_impl!(CriticalSection);
35+
critical_section::set_impl!(CriticalSection);
5036

5137
unsafe impl critical_section::Impl for CriticalSection {
5238
unsafe fn acquire() -> u8 {
@@ -60,7 +46,7 @@ unsafe impl critical_section::Impl for CriticalSection {
6046
}
6147
```
6248

63-
If you're writing a library crate that provides a custom impl, it is strongly recommended that
49+
If you're writing a library crate that provides an impl, it is strongly recommended that
6450
you only provide it if explicitly enabled by the user via a Cargo feature `critical-section-impl`.
6551
This allows the user to opt out from your impl to supply their own.
6652

avr-specs/avr-atmega328p.json

-27
This file was deleted.

rust-toolchain.toml

-12
This file was deleted.

src/lib.rs

+36-133
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
#![cfg_attr(docsrs, feature(doc_cfg))]
21
#![no_std]
3-
#![cfg_attr(target_arch = "avr", feature(llvm_asm))]
4-
#![cfg_attr(target_arch = "avr", feature(extended_key_value_attributes))]
52
#![doc = include_str!("../README.md")]
63

74
pub use bare_metal::CriticalSection;
@@ -58,141 +55,47 @@ pub fn with<R>(f: impl FnOnce(CriticalSection) -> R) -> R {
5855
}
5956
}
6057

61-
cfg_if::cfg_if! {
62-
if #[cfg(feature = "custom-impl")] {
63-
/// Methods required for a custom critical section implementation.
64-
///
65-
/// This trait is not intended to be used except when implementing a custom critical section.
66-
///
67-
/// Implementations must uphold the contract specified in [`crate::acquire`] and [`crate::release`].
68-
#[cfg_attr(docsrs, doc(cfg(feature = "custom-impl")))]
69-
pub unsafe trait Impl {
70-
/// Acquire the critical section.
71-
unsafe fn acquire() -> u8;
72-
/// Release the critical section.
73-
unsafe fn release(token: u8);
74-
}
75-
76-
/// Set the custom critical section implementation.
77-
///
78-
/// # Example
79-
///
80-
/// ```
81-
/// struct MyCriticalSection;
82-
/// critical_section::custom_impl!(MyCriticalSection);
83-
///
84-
/// unsafe impl critical_section::Impl for MyCriticalSection {
85-
/// unsafe fn acquire() -> u8 {
86-
/// // ...
87-
/// # return 0
88-
/// }
89-
///
90-
/// unsafe fn release(token: u8) {
91-
/// // ...
92-
/// }
93-
/// }
94-
///
95-
#[cfg_attr(docsrs, doc(cfg(feature = "custom-impl")))]
96-
#[macro_export]
97-
macro_rules! custom_impl {
98-
($t: ty) => {
99-
#[no_mangle]
100-
unsafe fn _critical_section_acquire() -> u8 {
101-
<$t as $crate::Impl>::acquire()
102-
}
103-
#[no_mangle]
104-
unsafe fn _critical_section_release(token: u8) {
105-
<$t as $crate::Impl>::release(token)
106-
}
107-
};
108-
}
109-
} else if #[cfg(cortex_m)] {
110-
#[no_mangle]
111-
unsafe fn _critical_section_acquire() -> u8 {
112-
let primask = cortex_m::register::primask::read();
113-
cortex_m::interrupt::disable();
114-
primask.is_active() as _
115-
}
116-
117-
#[no_mangle]
118-
unsafe fn _critical_section_release(token: u8) {
119-
if token != 0 {
120-
cortex_m::interrupt::enable()
121-
}
122-
}
123-
} else if #[cfg(target_arch = "avr")] {
124-
#[no_mangle]
125-
unsafe fn _critical_section_acquire() -> u8 {
126-
let mut sreg: u8;
127-
llvm_asm!(
128-
"in $0, 0x3F
129-
cli"
130-
: "=r"(sreg)
131-
::: "volatile"
132-
);
133-
sreg
134-
}
135-
136-
#[no_mangle]
137-
unsafe fn _critical_section_release(token: u8) {
138-
if token & 0x80 == 0x80 {
139-
llvm_asm!("sei" :::: "volatile");
140-
}
141-
}
142-
} else if #[cfg(target_arch = "riscv32")] {
143-
#[no_mangle]
144-
unsafe fn _critical_section_acquire() -> u8 {
145-
let interrupts_active = riscv::register::mstatus::read().mie();
146-
riscv::interrupt::disable();
147-
interrupts_active as _
148-
}
149-
150-
#[no_mangle]
151-
unsafe fn _critical_section_release(token: u8) {
152-
if token != 0 {
153-
riscv::interrupt::enable();
154-
}
155-
}
156-
} else if #[cfg(any(unix, windows, wasm, target_arch = "wasm32"))] {
157-
extern crate std;
158-
use std::sync::{Once, Mutex, MutexGuard};
159-
use core::cell::Cell;
160-
161-
static INIT: Once = Once::new();
162-
static mut GLOBAL_LOCK: Option<Mutex<()>> = None;
163-
static mut GLOBAL_GUARD: Option<MutexGuard<'static, ()>> = None;
164-
165-
std::thread_local!(static IS_LOCKED: Cell<bool> = Cell::new(false));
58+
/// Methods required for a custom critical section implementation.
59+
///
60+
/// This trait is not intended to be used except when implementing a custom critical section.
61+
///
62+
/// Implementations must uphold the contract specified in [`crate::acquire`] and [`crate::release`].
63+
pub unsafe trait Impl {
64+
/// Acquire the critical section.
65+
unsafe fn acquire() -> u8;
66+
/// Release the critical section.
67+
unsafe fn release(token: u8);
68+
}
16669

70+
/// Set the custom critical section implementation.
71+
///
72+
/// # Example
73+
///
74+
/// ```
75+
/// struct MyCriticalSection;
76+
/// critical_section::custom_impl!(MyCriticalSection);
77+
///
78+
/// unsafe impl critical_section::Impl for MyCriticalSection {
79+
/// unsafe fn acquire() -> u8 {
80+
/// // ...
81+
/// # return 0
82+
/// }
83+
///
84+
/// unsafe fn release(token: u8) {
85+
/// // ...
86+
/// }
87+
/// }
88+
///
89+
#[macro_export]
90+
macro_rules! set_impl {
91+
($t: ty) => {
16792
#[no_mangle]
16893
unsafe fn _critical_section_acquire() -> u8 {
169-
INIT.call_once(|| unsafe {
170-
GLOBAL_LOCK.replace(Mutex::new(()));
171-
});
172-
173-
// Allow reentrancy by checking thread local state
174-
IS_LOCKED.with(|l| {
175-
if !l.get() {
176-
let guard = GLOBAL_LOCK.as_ref().unwrap().lock().unwrap();
177-
GLOBAL_GUARD.replace(guard);
178-
l.set(true);
179-
1
180-
} else {
181-
0
182-
}
183-
})
94+
<$t as $crate::Impl>::acquire()
18495
}
185-
18696
#[no_mangle]
18797
unsafe fn _critical_section_release(token: u8) {
188-
if token == 1 {
189-
GLOBAL_GUARD.take();
190-
IS_LOCKED.with(|l| {
191-
l.set(false);
192-
});
193-
}
98+
<$t as $crate::Impl>::release(token)
19499
}
195-
} else {
196-
compile_error!("Critical section is not implemented for this target. Make sure you've specified the correct --target. You may need to supply a custom critical section implementation with the `custom-impl` feature");
197-
}
100+
};
198101
}

0 commit comments

Comments
 (0)