Skip to content

Commit 44dc22f

Browse files
authored
Merge pull request #312 from Ralith/elementwise-unordered-atomics
Tidy up unordered elementwise atomic memory intrinsics
2 parents bc57f53 + 9775f08 commit 44dc22f

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/mem.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type c_int = i16;
55
#[cfg(not(target_pointer_width = "16"))]
66
type c_int = i32;
77

8-
use core::intrinsics::{atomic_load_unordered, atomic_store_unordered, unchecked_div};
8+
use core::intrinsics::{atomic_load_unordered, atomic_store_unordered, exact_div};
99
use core::mem;
1010
use core::ops::{BitOr, Shl};
1111

@@ -63,9 +63,10 @@ pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
6363
0
6464
}
6565

66+
// `bytes` must be a multiple of `mem::size_of::<T>()`
6667
fn memcpy_element_unordered_atomic<T: Copy>(dest: *mut T, src: *const T, bytes: usize) {
6768
unsafe {
68-
let n = unchecked_div(bytes, mem::size_of::<T>());
69+
let n = exact_div(bytes, mem::size_of::<T>());
6970
let mut i = 0;
7071
while i < n {
7172
atomic_store_unordered(dest.add(i), atomic_load_unordered(src.add(i)));
@@ -74,9 +75,10 @@ fn memcpy_element_unordered_atomic<T: Copy>(dest: *mut T, src: *const T, bytes:
7475
}
7576
}
7677

78+
// `bytes` must be a multiple of `mem::size_of::<T>()`
7779
fn memmove_element_unordered_atomic<T: Copy>(dest: *mut T, src: *const T, bytes: usize) {
7880
unsafe {
79-
let n = unchecked_div(bytes, mem::size_of::<T>());
81+
let n = exact_div(bytes, mem::size_of::<T>());
8082
if src < dest as *const T {
8183
// copy from end
8284
let mut i = n;
@@ -95,18 +97,24 @@ fn memmove_element_unordered_atomic<T: Copy>(dest: *mut T, src: *const T, bytes:
9597
}
9698
}
9799

100+
// `T` must be a primitive integer type, and `bytes` must be a multiple of `mem::size_of::<T>()`
98101
fn memset_element_unordered_atomic<T>(s: *mut T, c: u8, bytes: usize)
99102
where
100103
T: Copy + From<u8> + Shl<u32, Output = T> + BitOr<T, Output = T>,
101104
{
102105
unsafe {
103-
let n = unchecked_div(bytes, mem::size_of::<T>());
106+
let n = exact_div(bytes, mem::size_of::<T>());
107+
108+
// Construct a value of type `T` consisting of repeated `c`
109+
// bytes, to let us ensure we write each `T` atomically.
104110
let mut x = T::from(c);
105111
let mut i = 1;
106112
while i < mem::size_of::<T>() {
107113
x = x << 8 | T::from(c);
108114
i += 1;
109115
}
116+
117+
// Write it to `s`
110118
let mut i = 0;
111119
while i < n {
112120
atomic_store_unordered(s.add(i), x);

0 commit comments

Comments
 (0)