<NickStevens[m]>
In the case of something to be read by a lay-person you are right. Use half-round. I was trying to have a discussion with you because there are legitimate uses for other rounding methods. But I think you assume I'm somehow attacking you, which I reall am not!
<dirbaio[m]>
hence I said if you can round (aka "half-round") then you should
<NickStevens[m]>
s/reall/really/
<dirbaio[m]>
if you can
<NickStevens[m]>
Hence what you meant is half-round if you can. Scrolling back what you actually said is very different. You pointed out that my fixed point suggestion did not half-round, it took the floor. I 100% agree, that is a limitation of that admittedly-simple solution, and had you said just that I would have agreed an moved on. You then laughed for suggesting there are other methods of rounding. I was asking you to listen to me and
<NickStevens[m]>
you wanted to disengage. We got to an agreement eventually but it felt like an argument to you, for what was only a technical discussion. Please be better than that! The Rust community is better than that!
<dirbaio[m]>
you started the argument with "citation needed"
<dirbaio[m]>
> You then laughed for suggesting there are other methods of rounding
<dirbaio[m]>
No, I did not, that's your interpretation
<NickStevens[m]>
dirbaio[m]: I'm really sorry it read as an argument then! I really meant it as a joke and included a 😉 to indicate that.
<NickStevens[m]>
* Your message got split between my reply. It looked like you were replying to my comment about "I want to understand" with 😂. This is totally my misunderstanding.
<dirbaio[m]>
the "citation needed" came across as a bit snarky to me, as in "but actually there's exceptions"
<dirbaio[m]>
as a reply to my message which was stating "in general it's better to round"
<dirbaio[m]>
of course to all "in general X" there's always exceptions
<dirbaio[m]>
so I got a bit annoyed and overreacted, I'm sorry about that :(
<NickStevens[m]>
Ditto, I'm sorry too. This is why I kept pressing, I really thought we were just talking past each other and I think we were. I'm glad we've got it straightened out!
<NickStevens[m]>
I'll do better on how I react to things like that too, it was too much like how I'd reply to a friend who'd know I was joking.
dsvsdveg[m] has joined #rust-embedded
<dsvsdveg[m]>
i'm looking to write a library for a sensor, the sensor is MAX30100, there is a C lib for it, what are your advice for it guys?
djdisodo[m] has quit [Quit: Idle timeout reached: 172800s]
<thejpster[m]>
(beta now complains about my use of static mut ...)
<thejpster[m]>
and the crate has deny(warnings) set, and it's a path dependency. So really I was asking for trouble.
ryan-summers[m] has joined #rust-embedded
<ryan-summers[m]>
I actually just hit this with a usb-device example and the quick fix was to wrap the static mut in an UnsafeCell
<ryan-summers[m]>
Then you can just use UnsafeCell::get_mut() instead of referencing the buffer directly because UnsafeCell handles the synchronization of the underlying data properly
IlPalazzo-ojiisa has joined #rust-embedded
<dirbaio[m]>
> because UnsafeCell handles the synchronization of the underlying data properly
<dirbaio[m]>
no it doesn't. `static mut X: u32` and `static X: UnsafeCell<u32>` are exactly equivalent, they both do no synchronization at all.
<dirbaio[m]>
they're equally unsafe/dangerous
<Lumpio->
_well achtually_ UnsafeCell does give you some etra powers - for example getting an immutable reference to that "static mut" and then changing the data would be undefined behavior, but having a immutable reference to the UnsafeCell and changing what's inside it is ok
ivmarkov[m] has joined #rust-embedded
<ivmarkov[m]>
But then what's the point of using UnsafeCell in the first place? I think it is all about interior mutability after all...
<thejpster[m]>
dirbaio: except one gives you a warning and one does not...
<thejpster[m]>
but yes, UnsafeCell requires you to play human borrow checker
<ivmarkov[m]>
Lumpio-: You can't change what is inside by using immutable ref only.
<ryan-summers[m]>
Hmm indeed if its unsafe but doesn't warn, that seems problematic
<ryan-summers[m]>
The links for that warning indicated that a synchronization primitive like UnsafeCell would make this all safe
<Lumpio->
ivmarkov[m]: You can change what's inside an UnsafeCell with an immutable reference. That's the entire point of UnsafeCell.
<dirbaio[m]>
unsafecell is not a synchronization primitive! :D
<Lumpio->
ryan-summers[m]: What's unsafe but doesn't warn..?
<ivmarkov[m]>
ivmarkov[m]: You need to do it via raw mut ptr, which is unsafe.
<dirbaio[m]>
it's a "hey compiler I know what I'm doing, please trust me". it doesn't actually do anything.
<ryan-summers[m]>
If you use UnsafeCell::get_mut() on nightly, it doesn't warn about a static mut reference
<ivmarkov[m]>
Lumpio-: Nope.
<ryan-summers[m]>
Not sure if it can though tbh?
<dirbaio[m]>
it's 100% on you to ensure you never have two `&mut`s to that memory at the same time, or you get UB
<ryan-summers[m]>
s/though/thoug/
<dirbaio[m]>
both with static mut and with static UnsafeCell
<Lumpio->
ryan-summers[m]: That should be fine because get_mut takes &mut self
<dirbaio[m]>
they're exactly equivalent
<dirbaio[m]>
and both are unsafe
<dirbaio[m]>
so they require unsafe{}
<ivmarkov[m]>
ryan-summers[m]: But you need mut to the unsafecell itself which kind of makes it a moot point.
<dirbaio[m]>
the reason they're adding this extra warning to static mut is to get people to stop using static mut
<ryan-summers[m]>
Yeah but then if you make it a static mut UnsafeCell, you can call UnsafeCell::get_mut with no compiler warning like you'd get without the cell
<ryan-summers[m]>
No unsafe was required
<Lumpio->
really
<ryan-summers[m]>
* ~~No unsafe was required~~ This was a lie
<ivmarkov[m]>
ivmarkov[m]: At least not in a safe way.
<dirbaio[m]>
static mut UnsafeCell is pointless, you have 2 "sources of mutability" there. if you're using UnsafeCell you should use just static
<ryan-summers[m]>
No, my bad, the initial access of the static mut did need unsafe. Dario is right here
<ryan-summers[m]>
What's the best way to deal with this then honestly?
<dirbaio[m]>
static UnsafeCell
<ryan-summers[m]>
I don't want to know/care about all the lifetime reference aliasing shenanigans. I just want to use static mut buffers
<ryan-summers[m]>
But then how do you turn an i.e. `static UnsafeCell` into a `&mut [u8]`?
<ryan-summers[m]>
* But then how do you turn an i.e. `static UnsafeCell<[u8; N>` into a `&mut [u8]`?
<Lumpio->
.get() as *mut u8
<ryan-summers[m]>
* But then how do you turn an i.e. `static UnsafeCell<[u8; N]>` into a `&mut [u8]`?
<Lumpio->
.get() as *mut u8 as &mut u8 ?
<ryan-summers[m]>
Isn't that the exact same issue though?
<ryan-summers[m]>
I.e. that's the same aliasing issue that they're avoiding. You're just working around their warning
<dirbaio[m]>
`unsafe { &mut *STATIC.get() }`
<ryan-summers[m]>
Is that not doing exactly what this warning is telling us not to do?
<Lumpio->
That is ok to do - as long as you never have that &mut exist twice at the same time
<dirbaio[m]>
yes
<dirbaio[m]>
that's my point
<dirbaio[m]>
the warning is to steer users away from static mut
<Lumpio->
The warning is telling you to be _really careful_, not to not do it.
<dirbaio[m]>
because it's deemed too easy to misuse
<Lumpio->
Although it would be preferable to not do it at all
<ryan-summers[m]>
Gotcha, so if we can guarantee there's only ever one reference, we're a-ok?
<dirbaio[m]>
and it's too easy for Rust newcomers to end up using static mut becuase it's the "obvious" way to do global mutable state
<Lumpio->
Yes but how are you gonna guarantee that heh
<ryan-summers[m]>
Yeah ikr. I was thinking option wrapping like a singleton?
<Lumpio->
I know what you're working on, do you have a generally usable Mutex or something available for that
<ryan-summers[m]>
In end applications that's fine because you can usually guarantee that, given that you only do setup once
<dirbaio[m]>
there's talks about removing static mut entirely
<dirbaio[m]>
* there's talks about removing static mut entirely, even
<ryan-summers[m]>
Lumpio-: my specific use case right now is for the `usb_device` test class, so it's not that big of a deal. Just curious what the preferred approach would be
<Lumpio->
yeah static UnsafeCell ought to be enough for everyone
<dirbaio[m]>
and yeah UnsafeCell is equally bad, but since it's harder to find and more "scary sounding" they're hoping it's less likely to trap Rust novices
<Lumpio->
Yes I saw it because it pings me for every PR...
<ryan-summers[m]>
Heh sorry, you can unsubscribe
diondokter[m] has joined #rust-embedded
<diondokter[m]>
Lumpio-: It's much more annoying to use though and the workaround is just as unsafe
<dirbaio[m]>
diondokter[m]: yeah I don't like the change either 🤷
<Lumpio->
No no I'm just curious to see what's going on
<Lumpio->
I tried avoiding the "forced user supplied buffer" in there for the longest time heh
<ryan-summers[m]>
Yeah but honestly I don't know if there's a better way. Open to other ideas too
<Lumpio->
Because it's yet another rigmarole to get a device going
<dirbaio[m]>
I do agree it'd be better if static mut didn't exist because it's a trap and you can already do it with static UnsafeCell... but now that it already exists, removing is quite the unnecessary churn :(
<ryan-summers[m]>
But it's worked well for me on an MQTT client and smoltcp seems to do well with it
<Lumpio->
But I could never come up with a good way to have some kind of buffer by default but allow supplying a larger one when needed...
<ryan-summers[m]>
Alright so the tl;dr here is change nothing and keep being as unsafe as we always have been, since we're embedded and we Know What We're Doing (tm)
<Lumpio->
Was there already a general solution for "DMA buffers" somewhere?
<Lumpio->
I.e. global buffers that need to live across functions and somehow still be safely accessible
<ryan-summers[m]>
Actually, given that this is all equally unsafe, is there a difference between using `&mut *UnsafeCell::get()` and `unsafe { UnsafeCell::get_mut() }`?
<Lumpio->
Because this could use a similar thing
<Lumpio->
ryan-summers[m]: Yes, get_mut requires &mut self to begin with, and then you need a "static mut UnsafeCell" which is weird
<Lumpio->
get takes only &self so it can be done without a mutable reference to the UnsafeCell itself
<ryan-summers[m]>
Fair
<Lumpio->
The "get_mut(&mut self, ...)" pattern for potentially shared data is pretty common, stuff like Rc and RefCell have it - because the &mut self already guarantees that there's only one reference
<dirbaio[m]>
ryan-summers[m]: you can't call `get_mut` on a static
<dirbaio[m]>
* on a (non-mut) static
<ryan-summers[m]>
I meant if the UnsafeCell was mut, but was correctly pointed out that we should make it non-mut
<dirbaio[m]>
if you do use static mut UnsafeCell then they are equivalent ... I think
<dirbaio[m]>
it's odd that the lint doesn't trigger for `.get_mut()` , it's supposed to trigger when you take references to the static mut, and doing `STATIC_MUT.get_mut()` definitely takes a refernece (the `&mut self` for the UnsafeCell method call...)
<Lumpio->
What lint are you talking about?
<Lumpio->
I don't see any warnings using a static mut inside an unsafe{} block
<ryan-summers[m]>
But it's saying that it has to be. Thus is it not possible to have a static UnsafeCell at all?
<dirbaio[m]>
SyncUnsafeCell is Sync, but in an "unchecked" way
<dirbaio[m]>
it's even more "yolo just trust me" than UnsafeCell :D
<ryan-summers[m]>
So a static UnsafeCell cannot exist then I think?
<ryan-summers[m]>
Because it's never Sync, but static has to be Sync
<explodingwaffle1>
(syncunsafecell isn't magic, you could just copy paste it if you need it on stable. there's probably a crate for it)
<ryan-summers[m]>
Given that,I don't know how I could ever do this without a static mut then without the new nightly syncunsafecell?
<ryan-summers[m]>
Like.... is this even possible with edition 2024 rust currently?
<ryan-summers[m]>
I'm not sure it is, which seems problematic
<dirbaio[m]>
yeah you have to write your own SyncUnsafeCell
<ryan-summers[m]>
Well that sucks
<dirbaio[m]>
it does :(
<ryan-summers[m]>
I guess I'll leave it as a static mut UnsafeCell for now and we can wait for SyncUnsafeCell to stabilize
<ryan-summers[m]>
Anyways thanks for the discussion. Sounds like there's definitely some more work on the "Remove static mut" front before its usable for embedded
<ryan-summers[m]>
Yeah but the crux right now is that there's no way to avoid this issue on stable rust without a custom type
<ryan-summers[m]>
But it feels like this is something core should have, and not some random crate to solve the problem
IlPalazzo-ojiisa has quit [Remote host closed the connection]
<JamesMunns[m]>
"solve the problem" - IMO, there is no one "fixes it" type, like yeah `SyncUnsafeCell` would be easier to reach for, but doesn't help you with the actual thing you need to be careful about, which is actually synchronizing access.
<ryan-summers[m]>
In our case we have no synchronization problems since these are just static buffers we're handing to driver constructors
<JamesMunns[m]>
idk, I do think that SyncUnsafeCell should exist, or something.
IlPalazzo-ojiisa has joined #rust-embedded
IlPalazzo-ojiisa has quit [Quit: Leaving.]
kenny has quit [Quit: WeeChat 4.2.1]
ello has quit [Ping timeout: 256 seconds]
kenny has joined #rust-embedded
ello has joined #rust-embedded
kenny has quit [Quit: WeeChat 4.2.1]
kenny has joined #rust-embedded
<thejpster[m]>
you could just get the linker to allocate some space and give you a symbol with an address that happens to match the start of your region.
<thejpster[m]>
I think James Munns 's panic-into-a-ram-buffer crate does this?
<JamesMunns[m]>
(using this at all within Rust itself IMO is sort of sketch)
<JamesMunns[m]>
I don't actually like how I implemented panic-persist anymore, and it's on my list to rewrite it with grounded.
<thejpster[m]>
ah ha ha, I quoted it as a "good example" just the other day :/
<JamesMunns[m]>
like, I'd rather have the compiler alloc the space (which lets me name the static and get size and stuff "in band")
<JamesMunns[m]>
thejpster[m]: it's not the worst, but there were some things that were questionably sound IIRC
<JamesMunns[m]>
atomicu8 is just `UnsafeCell<u8>` under the hood
<JamesMunns[m]>
like it works, but it's indirect.
<thejpster[m]>
yeah, but it's sync ;)
<JamesMunns[m]>
anyway, I'll shut up and stop arguing. I have opinions about static mut (and various linker shenanigans) that I think have been suggested and are Not Great for various reasons, no time to write them, and I feel like I should just let people do what they want instead of nagging until I can make a reasonable case about it.
<thejpster[m]>
My biggest issue was the third-party type I want to share not being Sync. So I put it in a wrapper and made the wrapper sync.
<thejpster[m]>
I can see why the Radio HAL wants to ensure the clock object lives forever (so the clocks cannot be de-initialised), but it's ugly as hell.
Abhishek_ has quit [Read error: Connection reset by peer]
Abhishek_ has joined #rust-embedded
IlPalazzo-ojiisa has quit [Remote host closed the connection]
<JamesMunns[m]>
I might be able to relax the T: Sync bound to T: Send, like you would for a mutex. Unsure
Guest7282 has left #rust-embedded [Error from remote client]
ragarnoy[m] has joined #rust-embedded
<ragarnoy[m]>
Hey! just open sourced a rust embedded library for radar sensor interfacing, made a post about it with details, I'm looking for feedback !