@@ -5,7 +5,7 @@ type c_int = i16;
5
5
#[ cfg( not( target_pointer_width = "16" ) ) ]
6
6
type c_int = i32 ;
7
7
8
- use core:: intrinsics:: { atomic_load_unordered, atomic_store_unordered, unchecked_div } ;
8
+ use core:: intrinsics:: { atomic_load_unordered, atomic_store_unordered, exact_div } ;
9
9
use core:: mem;
10
10
use core:: ops:: { BitOr , Shl } ;
11
11
@@ -63,9 +63,10 @@ pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
63
63
0
64
64
}
65
65
66
+ // `bytes` must be a multiple of `mem::size_of::<T>()`
66
67
fn memcpy_element_unordered_atomic < T : Copy > ( dest : * mut T , src : * const T , bytes : usize ) {
67
68
unsafe {
68
- let n = unchecked_div ( bytes, mem:: size_of :: < T > ( ) ) ;
69
+ let n = exact_div ( bytes, mem:: size_of :: < T > ( ) ) ;
69
70
let mut i = 0 ;
70
71
while i < n {
71
72
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:
74
75
}
75
76
}
76
77
78
+ // `bytes` must be a multiple of `mem::size_of::<T>()`
77
79
fn memmove_element_unordered_atomic < T : Copy > ( dest : * mut T , src : * const T , bytes : usize ) {
78
80
unsafe {
79
- let n = unchecked_div ( bytes, mem:: size_of :: < T > ( ) ) ;
81
+ let n = exact_div ( bytes, mem:: size_of :: < T > ( ) ) ;
80
82
if src < dest as * const T {
81
83
// copy from end
82
84
let mut i = n;
@@ -95,18 +97,24 @@ fn memmove_element_unordered_atomic<T: Copy>(dest: *mut T, src: *const T, bytes:
95
97
}
96
98
}
97
99
100
+ // `T` must be a primitive integer type, and `bytes` must be a multiple of `mem::size_of::<T>()`
98
101
fn memset_element_unordered_atomic < T > ( s : * mut T , c : u8 , bytes : usize )
99
102
where
100
103
T : Copy + From < u8 > + Shl < u32 , Output = T > + BitOr < T , Output = T > ,
101
104
{
102
105
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.
104
110
let mut x = T :: from ( c) ;
105
111
let mut i = 1 ;
106
112
while i < mem:: size_of :: < T > ( ) {
107
113
x = x << 8 | T :: from ( c) ;
108
114
i += 1 ;
109
115
}
116
+
117
+ // Write it to `s`
110
118
let mut i = 0 ;
111
119
while i < n {
112
120
atomic_store_unordered ( s. add ( i) , x) ;
0 commit comments