Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation errors due to missing atomics even though atomic feature is not enabled #214

Closed
arctic-alpaca opened this issue Jan 28, 2023 · 3 comments

Comments

@arctic-alpaca
Copy link

Hi,
I'm trying to use bitvec with aya which uses bpf-linker to create BPF programs. Atomics are not available for the BPF targets.

As per readme, bitvec = {version = "1.0.1", default-features = false} should disable the use of atomics in bitvec but I still get compilation errors:

error[E0432]: unresolved imports `core::sync::atomic::AtomicBool`, `core::sync::atomic::AtomicI8`, `core::sync::atomic::AtomicU8`
  --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/lib.rs:44:34
   |
44 |         use core::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};
   |                                  ^^^^^^^^^^  ^^^^^^^^  ^^^^^^^^ no `AtomicU8` in `sync::atomic`
   |                                  |           |
   |                                  |           no `AtomicI8` in `sync::atomic`
   |                                  no `AtomicBool` in `sync::atomic`
   |
help: a similar name exists in the module
   |
44 |         use core::sync::atomic::{AtomicBool, AtomicI64, AtomicU8};
   |                                              ~~~~~~~~~
help: a similar name exists in the module
   |
44 |         use core::sync::atomic::{AtomicBool, AtomicI8, AtomicU64};
   |                                                        ~~~~~~~~~

error[E0432]: unresolved imports `core::sync::atomic::AtomicI16`, `core::sync::atomic::AtomicU16`
  --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/lib.rs:47:34
   |
47 |         use core::sync::atomic::{AtomicI16, AtomicU16};
   |                                  ^^^^^^^^^  ^^^^^^^^^ no `AtomicU16` in `sync::atomic`
   |                                  |
   |                                  no `AtomicI16` in `sync::atomic`
   |
help: a similar name exists in the module
   |
47 |         use core::sync::atomic::{AtomicI64, AtomicU16};
   |                                  ~~~~~~~~~
help: a similar name exists in the module
   |
47 |         use core::sync::atomic::{AtomicI16, AtomicU64};
   |                                             ~~~~~~~~~

error[E0432]: unresolved imports `core::sync::atomic::AtomicI32`, `core::sync::atomic::AtomicU32`
  --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/lib.rs:50:34
   |
50 |         use core::sync::atomic::{AtomicI32, AtomicU32};
   |                                  ^^^^^^^^^  ^^^^^^^^^ no `AtomicU32` in `sync::atomic`
   |                                  |
   |                                  no `AtomicI32` in `sync::atomic`
   |
help: a similar name exists in the module
   |
50 |         use core::sync::atomic::{AtomicI64, AtomicU32};
   |                                  ~~~~~~~~~
help: a similar name exists in the module
   |
50 |         use core::sync::atomic::{AtomicI32, AtomicU64};
   |                                             ~~~~~~~~~

error[E0412]: cannot find type `AtomicBool` in module `core::sync::atomic`
  --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/types.rs:10:43
   |
10 |     if atomic(bool) { core::sync::atomic::AtomicBool }
   |                                           ^^^^^^^^^^ not found in `core::sync::atomic`

error[E0412]: cannot find type `AtomicI8` in module `core::sync::atomic`
    --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/types.rs:16:40
     |
16   |       if atomic(8) { core::sync::atomic::AtomicI8 }
     |                                          ^^^^^^^^ help: a struct with a similar name exists: `AtomicI64`
     |
    ::: /home/arctic-alpaca/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:2858:1
     |
2858 | / atomic_int! {
2859 | |     cfg(target_has_atomic = "64"),
2860 | |     cfg(target_has_atomic_equal_alignment = "64"),
2861 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
2875 | |     i64 AtomicI64 ATOMIC_I64_INIT
2876 | | }
     | |_- similarly named struct `AtomicI64` defined here

error[E0412]: cannot find type `AtomicU8` in module `core::sync::atomic`
    --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/types.rs:22:40
     |
22   |       if atomic(8) { core::sync::atomic::AtomicU8 }
     |                                          ^^^^^^^^ help: a struct with a similar name exists: `AtomicU64`
     |
    ::: /home/arctic-alpaca/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:2878:1
     |
2878 | / atomic_int! {
2879 | |     cfg(target_has_atomic = "64"),
2880 | |     cfg(target_has_atomic_equal_alignment = "64"),
2881 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
2895 | |     u64 AtomicU64 ATOMIC_U64_INIT
2896 | | }
     | |_- similarly named struct `AtomicU64` defined here

error[E0412]: cannot find type `AtomicI16` in module `core::sync::atomic`
    --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/types.rs:28:41
     |
28   |       if atomic(16) { core::sync::atomic::AtomicI16 }
     |                                           ^^^^^^^^^ help: a struct with a similar name exists: `AtomicI64`
     |
    ::: /home/arctic-alpaca/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:2858:1
     |
2858 | / atomic_int! {
2859 | |     cfg(target_has_atomic = "64"),
2860 | |     cfg(target_has_atomic_equal_alignment = "64"),
2861 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
2875 | |     i64 AtomicI64 ATOMIC_I64_INIT
2876 | | }
     | |_- similarly named struct `AtomicI64` defined here

error[E0412]: cannot find type `AtomicU16` in module `core::sync::atomic`
    --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/types.rs:34:41
     |
34   |       if atomic(16) { core::sync::atomic::AtomicU16 }
     |                                           ^^^^^^^^^ help: a struct with a similar name exists: `AtomicU64`
     |
    ::: /home/arctic-alpaca/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:2878:1
     |
2878 | / atomic_int! {
2879 | |     cfg(target_has_atomic = "64"),
2880 | |     cfg(target_has_atomic_equal_alignment = "64"),
2881 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
2895 | |     u64 AtomicU64 ATOMIC_U64_INIT
2896 | | }
     | |_- similarly named struct `AtomicU64` defined here

error[E0412]: cannot find type `AtomicI32` in module `core::sync::atomic`
    --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/types.rs:40:41
     |
40   |       if atomic(32) { core::sync::atomic::AtomicI32 }
     |                                           ^^^^^^^^^ help: a struct with a similar name exists: `AtomicI64`
     |
    ::: /home/arctic-alpaca/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:2858:1
     |
2858 | / atomic_int! {
2859 | |     cfg(target_has_atomic = "64"),
2860 | |     cfg(target_has_atomic_equal_alignment = "64"),
2861 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
2875 | |     i64 AtomicI64 ATOMIC_I64_INIT
2876 | | }
     | |_- similarly named struct `AtomicI64` defined here

error[E0412]: cannot find type `AtomicU32` in module `core::sync::atomic`
    --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-0.7.0/src/types.rs:46:41
     |
46   |       if atomic(32) { core::sync::atomic::AtomicU32 }
     |                                           ^^^^^^^^^ help: a struct with a similar name exists: `AtomicU64`
     |
    ::: /home/arctic-alpaca/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:2878:1
     |
2878 | / atomic_int! {
2879 | |     cfg(target_has_atomic = "64"),
2880 | |     cfg(target_has_atomic_equal_alignment = "64"),
2881 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
2895 | |     u64 AtomicU64 ATOMIC_U64_INIT
2896 | | }
     | |_- similarly named struct `AtomicU64` defined here

This looks like it is similar to the issue raised in the radium repo ferrilab/ferrilab#1.

@arctic-alpaca
Copy link
Author

arctic-alpaca commented Jan 29, 2023

As suggested in ferrilab/ferrilab#1, I tried to (naively) update bitvec to radium 1.0.0 here: https://github.com/arctic-alpaca/bitvec
The bitvec tests seem to pass as before the update but when using the updated version in my project, I encountered this error from radium:

error[E0277]: `*mut T` cannot be sent between threads safely
   --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-1.0.0/src/types.rs:201:19
    |
201 |               type Nucleus = $radium$(<$t>)?;
    |                              ^^^^^^^^^^^^^ `*mut T` cannot be sent between threads safely
...
223 | / alias! {
224 | |     "8" => {
225 | |         bool => RadiumBool => AtomicBool;
226 | |         i8 => RadiumI8 => AtomicI8;
...   |
249 | |     }
250 | | }
    | |_- in this macro invocation
    |
    = help: the trait `Send` is not implemented for `*mut T`
    = help: the trait `Send` is implemented for `&T`
    = note: required for `Cell<*mut T>` to implement `Send`
note: required by a bound in `marker::Nuclear::Nucleus`
   --> /home/arctic-alpaca/.cargo/registry/src/github.51.al-1ecc6299db9ec823/radium-1.0.0/src/marker.rs:45:38
    |
45  |     type Nucleus: Radium<Item = Self> + Send;
    |                                         ^^^^ required by this bound in `Nuclear::Nucleus`
    = note: this error originates in the macro `alias` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.

After removing the Send bound (https://github.com/arctic-alpaca/ferrilab), I was able to use bitvec in my project. I do not know what the implication/effect of removing the Send bound is or if my simple update of bitvec has any side effects. If desired, I'd be happy to create a PR.

EDIT: After realizing you are migrating to a monorepo, I pushed the bitvec changes to the monorepo fork: https://github.com/arctic-alpaca/ferrilab

@myrrlyn
Copy link
Collaborator

myrrlyn commented Apr 12, 2023

Hi! I apologize for the long delay; I have had a very stressful winter and have not had the time or energy to check this repository in a timely manner. I'm trying to catch up now.

Thank you for your time investigating this, and for duplicating effort in the monorepo. radium is a really annoying project to manage. Being able to punt to the compiler as of Rust 1.60 is a huge relief, and I have already migrated to radium 1 in my working copy.

I suspect that the reason for your initial error is just that radium 0 requires that we manually process target definitions taken from the compiler, and I don't think we collected BPF targets last time we did that.

I am pretty sure I can migrate to radium 1 without a major-version bump, so I intend to do so in bitvec 1.1.


If you require a Send bound, then Nucleus is failing as expected when your final target doesn't have the requisite atomic. It silently falls back to Cell, which isn't threadsafe. You'd have to either #[cfg]-guard your type on the presence of the needed atomic, or do exactly what you did: remove the bound here, and then encounter compiler errors when you attempt to do multithreading on a target without proper atomics.

The advantage is that now your errors occur at the use site, not at the declaration site: thread::spawn will fail, instead of your typedecl.

I think the fact that Cell<*mut T> isn't Send is an irritating discrepancy: AtomicPtr is Send, and Cells are Send when their interior is. The reason that Cell<*mut T> isn't Send is that the pointer might become invalid to dereference if a foreign thread has a time delay between receipt and use. This, however, is equally true of the pointer value stored inside an AtomicPtr!

Unfortunately, I'm pretty sure impl<T> Send for Cell<*mut T> collides with impl<T: Send> Send for Cell<T> (pointers aren't fundamental types like references are), and removing the Send impl on atomic pointers is a breaking change, so we're just left with it.

I hope this helps!

@myrrlyn myrrlyn closed this as completed Apr 12, 2023
@ProfFan
Copy link

ProfFan commented Nov 6, 2023

Hello @myrrlyn thanks for the amazing library. However, I think this issue has not been solved, the main branch still refers to radium v0.7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants