Giter Site home page Giter Site logo

Comments (17)

therealprof avatar therealprof commented on August 22, 2024

Now I am confused. Didn't you tell me that &'static mut are a bad idea not too long ago?

from rtic.

japaric avatar japaric commented on August 22, 2024

What? No. &'static mut is fine. The problem is aliasing the &'static mut reference, which must be unique. Simple, actually memory unsafe, functions like the one below result in mutable aliasing (and break Rust memory model) so those are a bad idea:

fn foo() -> &'static mut u32 {
    static mut FOO: u32 = 0;
    unsafe { &mut FOO }
}

let a: &'static mut u32 = foo();
let b: &'static mut u32 = foo();

// BAD `a` and `b` point to the same thing
assert_ne!(a as *const _ as usize, b as *const _ as usize);

But if you have a mechanism to guarantee the uniqueness of the &'static mut reference, like what's proposed in this RFC, then you are good to go.

from rtic.

therealprof avatar therealprof commented on August 22, 2024

I neither see how your suggestion automagically fixes the possibility of mutable aliasing nor how that would break Rusts memory model (since you can only initialise them with known types and const functions anyway, Rust will always be aware of size and place). There're plenty of applications where concurrent access is just fine or even expected and/or out of program control (as in your DMA example).

from rtic.

jonas-schievink avatar jonas-schievink commented on August 22, 2024

@therealprof Under this proposal, mutable references are only handed out by RTFM to the init function (uniqueness is enforced by the app! macro - when a resource is used by init, it may not be used by any other task). Aliasing &muts, static or not, result in insta-UB (also see https://doc.rust-lang.org/nomicon/transmutes.html). (Edit: Maybe, maybe not, who knows? And who needs a memory model anyways?)

(I've only skimmed this proposal, but it looks safe - and a safe and simple abstraction over DMA is totally awesome!)

from rtic.

therealprof avatar therealprof commented on August 22, 2024

There's no transmute happening in the example brought up by @japaric and the transmute chapter does not handle aliasing at all as far as I can see, that would be https://doc.rust-lang.org/nomicon/aliasing.html . As soon as you want to use shared memory or hand off the pointer for the use of DMA you're accepting the fact that you (or the hardware) is aliasing memory anyway. And for a lot of applications that is just okay.

from rtic.

jonas-schievink avatar jonas-schievink commented on August 22, 2024

@therealprof You might be right about the safety of aliasing. Certainly, as it stands, Rust defers the UB decision to LLVM, which allows aliasing noalias/&mut pointers as long as their uses don't violate aliasing rules. However, Rust doesn't specify LLVM's behaviour. In fact, Rust doesn't really specify anything.

But giving the user aliasing &mut allows UB in safe code, which is a big no-no. I also don't understand your point about DMA - it also needs mutable access to the data, but the program doesn't need to (and isn't allowed to) access the memory while the transfer is in progress, and this is perfectly expressed by this proposal (peripherals and memory involved in a transfer are unusable until the application waits for the transfer to complete - no conflicting access is happening).

from rtic.

perlindgren avatar perlindgren commented on August 22, 2024

from rtic.

therealprof avatar therealprof commented on August 22, 2024

@jonas-schievink A lot of languages implemented on LLVM do allow aliasing pointers so there shouldn't be any problem there.

My point re: aliasing was that aliasing (whether it happens in software an/or hardware is not relevant) is not necessarily a bad thing and sometimes quite expected.

Anyhow, I'm very much in favour of this proposal despite the confusion around the badness of aliased mut statics...

from rtic.

pftbest avatar pftbest commented on August 22, 2024

@therealprof Other languages do not set noalias attribute on their pointers, so they don't have any problem with aliasing.

Here is a classical example of UB: https://godbolt.org/g/LrFMjL
Notice how removing pub keyword from function bar changes return value of abc

from rtic.

therealprof avatar therealprof commented on August 22, 2024

@pftbest Fully understood that you can do really bad stuff with aliased pointers.

from rtic.

pftbest avatar pftbest commented on August 22, 2024

you can do really bad stuff with aliased pointers

This is just a trivial example, the real code may be much more subtle. And it's not always about what you write, similar code may be generated after some optimization steps.

The whole idea of Rust is to make it impossible to trigger UB in a safe code. No matter how bad the code is, if it's in safe rust it should either not compile, or panic at runtime.

If you can trigger UB in a safe code that means your unsafe blocks are designed incorrectly.

from rtic.

hannobraun avatar hannobraun commented on August 22, 2024

@japaric Thanks for tagging me. I've looked over your proposal, and everything looks good to me, with two caveats:

  • I'm not intimitely familiar with the workings of &'static mut, so I might be missing something. It looks like you've done your homework though!
  • I'm largely unfamiliar with RTFM, so I might be missing something there, too.

I'm also a bit unclear on how this fits into the larger context. Specifically, how does this proposal relate to rust-embedded/embedded-hal#14? That proposal mentions static_ref::Ref, which seems to be a predecessor of Static. Am I correct in assuming that Static will be completely deprecated, even outside of RTFM?

It seems to me that Static wouldn't be useful, since it can only be created using unsafe, and once unsafe is an option, I can just create a &'static mut, and use that as suggested in this proposal.

from rtic.

japaric avatar japaric commented on August 22, 2024

@hannobraun

Specifically, how does this proposal relate to rust-embedded/embedded-hal#14?

This proposal is for RTFM. I think, though, that Static, previously static_ref::Ref{,Mut}, is
not enough to create memory safe DMA APIs (I haven't documented the mem::swap problem but I think
Static is not enough to prevent it). Thus I think that the standardized DMA API that will end
in embedded-hal should use &'static mut references, not Static. That raises the question: what
will be the fate of non-RTFM applications where it's not safe to create &'static mut references?

Except that I just thought of a way to safely create &'static mut references in non-RTFM
applications. There is no free lunch though: this approach will incur in non-elidable runtime
checks. Here's the idea: a macro that creates &'static mut references using the singleton check I
introduced in rust-embedded/svd2rust#157:

// this macro could be simplified: for instance `$ident` is kind of useless
macro_rules! alloc {
    (static $ident:ident: $ty:ty = $expr:expr) => {
      cortex_m::interrupt::free(unsafe {
          static mut USED: bool = false;

          if USED {
              None
          } else {
              static mut $ident: $ty = $expr;
              let e: &'static mut $ty = &mut $ident;
              USED = true;
              Some(e)
          }
      })
    }
}

let a = alloc!(static BUFFER: [u8; 16] = [0; 16]).unwrap();
let b = alloc!(static BUFFER: [u8; 16] = [0; 16]).unwrap();

// OK `a` and `b` are not aliases -- they are pointing to different `static` variables
assert_ne!(a.as_ptr(), b.as_ptr());

fn alias() -> &'static mut [u8; 16] {
    alloc!(static BUFFER: [u8; 16] = [0; 16]).unwrap()
}

let c = alias();
// this will panic! if it didn't it would create an alias to the `BUFFER` variable in `alias`
let d = alias();

Am I correct in assuming that Static will be completely deprecated, even outside of RTFM?

I think the only user of Static is RTFM so yeah it will probably vanish into nothingness after
this change.

from rtic.

therealprof avatar therealprof commented on August 22, 2024

@pftbest We're fully on the same page here and I'm absolutely not suggesting this to be used in any user facing crate.

from rtic.

hannobraun avatar hannobraun commented on August 22, 2024

@japaric Thanks for your reply. Interesting proposal. I don't have a firm opinion on the matter right now. Integrating DMA into one of my projects is on my todo list though, so I assume I'll have more to say then.

from rtic.

japaric avatar japaric commented on August 22, 2024

Since this has received positive feedback and no objections I'm going to rubber stamp the RFC and land the open PRs.

I'll send another PR to cortex-m to discuss a checked version of this that works without RTFM.

from rtic.

japaric avatar japaric commented on August 22, 2024

I'll send another PR to cortex-m to discuss a checked version of this that works without RTFM.

See rust-embedded/cortex-m#70. Feedback on the macro syntax is welcome!

from rtic.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.