Can atomics be memmapped?

Do atomics need to be initialized in a specific way or can they just be transmuted from their inner type? EDIT: yes

For example, is it okay to transmute a Vec<u64> to a Vec<AtomicU64>? EDIT: NO is the answer to this!

In my actual use case there is also the question of how that will interact with having that memory actually mem mapped:

use memmap2::MmapOptions;
use std::sync::atomic::AtomicU64;
use std::io::Write;
use std::fs::File;

let file = File::open("some_file.saved")?;
let mmap = unsafe { MmapOptions::new().map(&file)? };

let (prefix, shorts, suffix) = mmap.align_to_mut::<AtomicU64>();
assert!(prefix.is_empty() && suffix.is_empty());

let useful: &mut [AtomicU64] = shorts;

Is the above code correct if I only use the useful after this to make atomic changes?

As far as I know, atomics are only different in the instructions that are used to change/read them. I just want to make sure I am not doing something stupid.

Yes, it is valid to transmute an &[u8] into &[AtomicU8].

No. There are special rules regarding vectors. For those, you need to go through from_raw_parts rather than a normal transmute.

1 Like

Oh yeah, I ran into the Vec transmute thing before. I was just trying to give a simpler example but thanks for reminding me :slight_smile:

Are you sure? &[AtomicU8] gives you write access to the slice elements but &[u8] only gave you read access.

4 Likes

You should be able to go from &mut [u8] to &[AtomicU8] though, akin to AtomicU8::from_mut.

3 Likes

It is valid to transmute an &mut [u8] into &mut [AtomicU8]. But not shared references

4 Likes

Oops, I was too fast there. Thanks for keeping an eye on me! :sweat_smile:

Oh yeah nice find :slight_smile:

If you can transmute safely between those two types, why isn't there just a From impl or convert method that would compile as a no-op? And if there is such a method, why does it matter whether it can be transmuted?

Strictly speaking transmuting them still is UB as DST ref memory layout is unspecified. You can use std::slice::from_raw_parts_mut() to reconstruct it.

5 Likes

I am using the .align_to_mut() function which internally does exactly that. So all is good on my end I think. Thank god. :sweat_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.