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

Atomic::<u32>::is_lock_free() always returns false for ESP32 #32

Closed
usbalbin opened this issue Jan 12, 2023 · 2 comments · Fixed by #33
Closed

Atomic::<u32>::is_lock_free() always returns false for ESP32 #32

usbalbin opened this issue Jan 12, 2023 · 2 comments · Fixed by #33

Comments

@usbalbin
Copy link
Contributor

usbalbin commented Jan 12, 2023

Hi!

I am experimenting with atomic-rs on an embedded system with an ESP32 mcu using the esp-idf-hal crate with project generated from esp-idf-template.

However I am getting some unexpected results from Atomic::is_lock_free which seems to return false no matter what I throw at it.

Having a peek at how the cfgs are generated i understand it as the build script looking for core::sync::atomic::AtomicU32::compare_exchange being available(for has_atomic_u32). That does work fine in my manuall test below and AtomicU32 is otherwise available and usable.

use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported

fn main() {
    esp_idf_sys::link_patches(); // Added by esp-rs/esp-idf-template

    std::sync::atomic::AtomicU32::compare_exchange; // Works
    core::sync::atomic::AtomicU32::compare_exchange;// Works

    const _: () = assert!(core::mem::align_of::<u32>() == 4); // Works
    const _: () = assert!(core::mem::size_of::<u32>() == 4); // Works

    // Copy pasted from atomic-rs and commented out cfgs
    pub const fn atomic_is_lock_free<T>() -> bool {
        let size = core::mem::size_of::<T>();
        let align = core::mem::align_of::<T>();
    
        (/*cfg!(has_atomic_u8) & */ (size == 1) & (align >= 1))
            | (/*cfg!(has_atomic_u16) &*/ (size == 2) & (align >= 2))
            | (/*cfg!(has_atomic_u32) &*/ (size == 4) & (align >= 4))
            | (/*cfg!(has_atomic_u64) &*/ (size == 8) & (align >= 8))
            | (/*cfg!(has_atomic_u128) &*/ (size == 16) & (align >= 16))
    }

    const _: () = assert!(atomic_is_lock_free::<u32>()); // Works fine

    const _: () = assert!(atomic::Atomic::<u8>::is_lock_free()); // Does not work
    const _: () = assert!(atomic::Atomic::<u16>::is_lock_free());// Does not work
    const _: () = assert!(atomic::Atomic::<u32>::is_lock_free());// Does not work
    const _: () = assert!(atomic::Atomic::<u64>::is_lock_free());// Does not work
    
    println!("Hello, world!");
}

I do have

[unstable]
build-std = ["core"]

in my project. Could this be cuviper/autocfg#34 ? Is there any solution/work around :) My intention is to use this with my own enum type

@Amanieu
Copy link
Owner

Amanieu commented Jan 12, 2023

cfg(target_has_atomic = "N") is now stable (since Rust 1.60 I believe), so we could switch to using that instead of autocfg-based detection. A PR would be welcome!

@usbalbin
Copy link
Contributor Author

Great, thanks! I will have a look. No guarantees though :)

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

Successfully merging a pull request may close this issue.

2 participants