Skip to content

Commit 82284c4

Browse files
authored
feat(cordyceps): Initial support for non-CAS targets (#526)
This PR is a first attempt to allow building of `cordyceps` on non-CAS enabled targets, such as `thumbv6m-none-eabi`/Cortex-M0+/rp2040. Doing this as a first feature, prior to implementing a non-atomic and `critical_section` based version of TransferStack, in service of embassy-rs/embassy#4035. Rather than making a default-on "CAS" feature, we instead gate on `cfg(target_has_atomic = "ptr")`, which was [stabilized in 1.60](rust-lang/rust#93824), which currently has the meaning of "this target has CAS". This automatically gates-out `TransferStack` and `MpscQueue`, while the "mutable" collections can still be used.
1 parent e2394c2 commit 82284c4

File tree

6 files changed

+352
-277
lines changed

6 files changed

+352
-277
lines changed

.github/workflows/ci.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,26 @@ jobs:
244244
- name: run Miri tests
245245
run: just miri cordyceps
246246

247+
# run no-atomics target tests
248+
cordyceps_no_atomics_compat:
249+
needs: changed_paths
250+
if: needs.changed_paths.outputs.should_skip != 'true' || !fromJSON(needs.changed_paths.outputs.paths_result).cordyceps.should_skip
251+
runs-on: ubuntu-latest
252+
name: no-atomics compat (cordyceps)
253+
steps:
254+
- name: install rust toolchain
255+
run: rustup show
256+
- uses: actions/checkout@v4
257+
- name: run check
258+
# we add the target HERE instead of in the 'install rust toolchain' step
259+
# because we need the `rust-toolchain.toml` file to be checked out, otherwise
260+
# the target is only added for `stable`. We could also add this to the
261+
# `targets` item in the toolchain file, but that would be a waste for all
262+
# other tests.
263+
run: |
264+
rustup target add thumbv6m-none-eabi
265+
cargo check -p cordyceps --target thumbv6m-none-eabi
266+
247267
### maitake ###
248268

249269
# test with `--no-default-features`
@@ -313,6 +333,7 @@ jobs:
313333
- docs
314334
- cordyceps_loom
315335
- cordyceps_miri
336+
- cordyceps_no_atomics_compat
316337
- maitake_no_default_features
317338
- maitake_loom
318339
- maitake_miri

cordyceps/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,21 @@ than owning those values.
8686
*must* be pinned in memory; they may not move (or be dropped) while linked
8787
into an intrusive collection.
8888

89+
## Compatibility
90+
91+
Rudimentary support for targets without CAS (Compare and Swap) atomics, such as
92+
Cortex-M0+/`thumbv6m-none-eabi`, is provided, however not all structures and
93+
features may be available.
94+
95+
CAS atomic support is automatically detected with `cfg(target_has_atomic = "ptr")`,
96+
which notes that a [platform has support] for both load/store operations as well
97+
as support for CAS atomics.
98+
99+
No crate-level features are necessary to enable/disable structures that require
100+
CAS atomics.
101+
102+
[platform has support]: https://doc.rust-lang.org/reference/conditional-compilation.html#r-cfg.target_has_atomic
103+
89104
## about the name
90105

91106
In keeping with Mycelium's fungal naming theme, _Cordyceps_ is a genus of

cordyceps/src/lib.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
//! [`MpscQueue`]s can be used to efficiently share data from multiple
3535
//! concurrent producers with a consumer.
3636
//!
37+
//! This structure is only available if the target supports CAS (Compare and
38+
//! Swap) atomics.
39+
//!
3740
//! - **[`SortedList`]: a mutable, singly-linked list, with elements stored
3841
//! in sorted order.**
3942
//!
@@ -71,6 +74,9 @@
7174
//! A [`TransferStack`] can be used to efficiently transfer ownership of
7275
//! resources from multiple producers to a consumer, such as for reuse or
7376
//! cleanup.
77+
//!
78+
//! This structure is only available if the target supports CAS (Compare and
79+
//! Swap) atomics.
7480
#[cfg(feature = "alloc")]
7581
extern crate alloc;
7682
#[cfg(test)]
@@ -80,18 +86,33 @@ extern crate std;
8086
pub(crate) mod util;
8187

8288
pub mod list;
83-
pub mod mpsc_queue;
8489
pub mod sorted_list;
8590
pub mod stack;
8691

8792
#[doc(inline)]
8893
pub use list::List;
8994
#[doc(inline)]
90-
pub use mpsc_queue::MpscQueue;
91-
#[doc(inline)]
9295
pub use sorted_list::{SortedList, SortedListIter};
9396
#[doc(inline)]
94-
pub use stack::{Stack, TransferStack};
97+
pub use stack::Stack;
98+
99+
//
100+
// The following items are only available if we have atomics
101+
//
102+
#[cfg(target_has_atomic = "ptr")]
103+
pub mod mpsc_queue;
104+
105+
#[cfg(target_has_atomic = "ptr")]
106+
pub use has_cas_atomics::*;
107+
108+
#[cfg(target_has_atomic = "ptr")]
109+
mod has_cas_atomics {
110+
#[doc(inline)]
111+
pub use crate::mpsc_queue::MpscQueue;
112+
113+
#[doc(inline)]
114+
pub use crate::stack::TransferStack;
115+
}
95116

96117
pub(crate) mod loom;
97118

cordyceps/src/mpsc_queue.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ use core::{
2121
ptr::{self, NonNull},
2222
};
2323

24+
macro_rules! feature {
25+
(
26+
#![$meta:meta]
27+
$($item:item)*
28+
) => {
29+
$(
30+
#[cfg($meta)]
31+
$item
32+
)*
33+
}
34+
}
35+
2436
/// A multi-producer, single-consumer (MPSC) queue, implemented using a
2537
/// lock-free [intrusive] singly-linked list.
2638
///

0 commit comments

Comments
 (0)