jamesmunns / bbqueue

A SPSC, lockless, no_std, thread safe, queue, based on BipBuffers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support thumbv6 targets

jonas-schievink opened this issue · comments

Cortex-M0 based chips (eg. the nRF51 series) are thumbv6 only, which is missing some operations on atomics. Trying to build bbqueue for thumbv6m-none-eabi currently results in these errors:

error[E0599]: no method named `fetch_sub` found for type `core::sync::atomic::AtomicUsize` in the current scope
   --> /home/jonas/.cargo/registry/src/github.com-1ecc6299db9ec823/bbqueue-0.3.2/src/lib.rs:337:22
    |
337 |         self.reserve.fetch_sub(len - used, Relaxed);
    |                      ^^^^^^^^^

error[E0599]: no method named `fetch_add` found for type `core::sync::atomic::AtomicUsize` in the current scope
   --> /home/jonas/.cargo/registry/src/github.com-1ecc6299db9ec823/bbqueue-0.3.2/src/lib.rs:421:27
    |
421 |         let _ = self.read.fetch_add(used, Release);
    |                           ^^^^^^^^^

error[E0599]: no method named `swap` found for type `core::sync::atomic::AtomicBool` in the current scope
   --> /home/jonas/.cargo/registry/src/github.com-1ecc6299db9ec823/bbqueue-0.3.2/src/lib.rs:442:37
    |
442 |         assert!(!self.already_split.swap(true, Relaxed));
    |                                     ^^^^

The log crate also had this issue: rust-lang/log#285
It was worked around with my PR in rust-lang/log#325

The same will probably not really work for bbqueue, unfortunately, since that needs to be at least interrupt-safe.

Trying to use this crate for a project that uses an STM32F072, is there any chance of this getting fixed? Or is there a similar crate I can try? The commit and release functionality is perfect for the serial port buffering I have in mind...

The heapless crate also has an SPSC queue, but without the batch-commit interface (for now). It works on thumbv6.

For the SPSC queue in heapless we use a manually implemented atomic for the thumbv6 arch, maybe this can simply be copied here?
Link to impl: https://github.com/japaric/heapless/blob/5ffd0df2ccbbd0a89d2879f0ee4c7909b944b5fa/src/spsc/mod.rs#L101

@korken89 SPSC works with just stores and loads, but bbqueue uses (compare and) swap instructions too. On single-core MCUs, those could be implemented via critical sections, but that becomes unsound as soon as there's more than one core.

My preferred solution for this would be to add bbqueue-like functionality to the heapless SPSC queue, since that already has a lot of other desirable optimizations put into it (like being very light on memory usage, allowing to statically select both capacity and the index type, etc.).

Indeed, this is correct. Maybe we should shake life into rust-embedded/heapless#65 again. I think this would be a great addition!

As a note, I plan to support thumbv6 targets with a critical section in version 0.4.0. See #37 for information regarding this.

Closed by #37

Can you reopen this ?
I can't build bbqueue using target thumbv6m.

The errors shown by cargo.

error[E0599]: no method named `fetch_add` found for reference `&AtomicUsize` in the current scope
    --> /home/eragon/.cargo/registry/src/github.com-1ecc6299db9ec823/bbqueue-0.4.12/src/bbbuffer.rs:1264:16
     |
1264 |         atomic.fetch_add(val, order)
     |                ^^^^^^^^^ method not found in `&AtomicUsize`

error[E0599]: no method named `fetch_sub` found for reference `&AtomicUsize` in the current scope
    --> /home/eragon/.cargo/registry/src/github.com-1ecc6299db9ec823/bbqueue-0.4.12/src/bbbuffer.rs:1269:16
     |
1269 |         atomic.fetch_sub(val, order)
     |                ^^^^^^^^^ method not found in `&AtomicUsize`

error[E0599]: no method named `swap` found for reference `&AtomicBool` in the current scope
    --> /home/eragon/.cargo/registry/src/github.com-1ecc6299db9ec823/bbqueue-0.4.12/src/bbbuffer.rs:1274:16
     |
1274 |         atomic.swap(val, order)
     |                ^^^^ method not found in `&AtomicBool`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0599`.
error: could not compile `bbqueue`

Hey @Eragonfr, could you please confirm you've tried this with the thumbv6 feature active?

See the Cargo.toml or the docs for what I mean.

Excuse me, I haven't seen the feature.
It build with the correct feature enabled.
I didn't checked the doc before reporting because it's a dependency of rubble.

is it possible to auto-set the flag if the target is thumbv6 ?
Maybe by using platform specific dependencies

Unfortunately, these don't work for the sub-families (all these targets have the same arch).

For future releases, I plan to switch to atomic-polyfill, which uses a build.rs workaround to detect this.

I'm glad you are able to make it work!