Is there an unsafe memcpy w/o relying on a &mut reference? For instance I want to copy b2, b3, b4 into b at specified locations w/o relying on a &mut reference to b. Is this even possible?
let b : [u8; 100] = [0; 100];
let b2 : [u8; 10] = [1; 10];
let b3 : [u8; 10] = [2; 10];
let b4 : [u8; 10] = [3; 10];
use std::ptr::addr_of_mut;
let mut b: [u8; 100] = [0; 100];
let b2: [u8; 10] = [1; 10];
let b3: [u8; 10] = [2; 10];
let b4: [u8; 10] = [3; 10];
unsafe {
let b_ptr: *mut u8 = addr_of_mut!(b).cast::<u8>();
b_ptr.add(5).copy_from_nonoverlapping(b2.as_ptr(), 10);
b_ptr.add(20).copy_from_nonoverlapping(b3.as_ptr(), 10);
b_ptr.add(35).copy_from_nonoverlapping(b4.as_ptr(), 10);
}
println!("{b:?}");
However, writing to a raw pointer in this way still requires mutable access, so it is equivalent to first creating a &mut reference to a subslice of b then writing to that. So it might not solve your problem here. Why exactly are you trying not to rely on a &mut reference?
Thanks. Here is the larger context - I have a large buffer and I have multiple threads writing into it. Now I can get an offset into the larger buffer using atomics pretty easily. However when I copy into the buffer I don't want to rely on having &mut reference to it, because in order to do so I have to serialize the writes. I would like the writes to happen in parallel.
How have you shared the buffer, and how do threads coordinate on what slices they can write to so they don't overlap? (Note that a data race is UB no matter how you achieve it.)
You will need to write your own synchronization with UnsafeCell or you use [u8]::split_at_mut at some point to split the buffer in multiple independently writable parts.
I second this. Can you set up your parallel workers/threads/tasks to already take the target subslice, when they start to work on a subtask? This worked for me, using
No you don't if you perform borrow splitting. You can also rely on a parallelism crate such as Rayon that abstracts away these mundane details of writing parallel code.