@@ -148,53 +148,55 @@ fn test_calloc() {
148
148
149
149
#[ cfg( not( target_os = "windows" ) ) ]
150
150
fn test_memalign ( ) {
151
- // A normal allocation.
152
- unsafe {
153
- let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
154
- let align = 8 ;
155
- let size = 64 ;
156
- assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
157
- assert ! ( !ptr. is_null( ) ) ;
158
- assert ! ( ptr. is_aligned_to( align) ) ;
159
- ptr. cast :: < u8 > ( ) . write_bytes ( 1 , size) ;
160
- libc:: free ( ptr) ;
161
- }
151
+ for _ in 0 ..16 {
152
+ // A normal allocation.
153
+ unsafe {
154
+ let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
155
+ let align = 8 ;
156
+ let size = 64 ;
157
+ assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
158
+ assert ! ( !ptr. is_null( ) ) ;
159
+ assert ! ( ptr. is_aligned_to( align) ) ;
160
+ ptr. cast :: < u8 > ( ) . write_bytes ( 1 , size) ;
161
+ libc:: free ( ptr) ;
162
+ }
162
163
163
- // Align > size.
164
- unsafe {
165
- let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
166
- let align = 64 ;
167
- let size = 8 ;
168
- assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
169
- assert ! ( !ptr. is_null( ) ) ;
170
- assert ! ( ptr. is_aligned_to( align) ) ;
171
- ptr. cast :: < u8 > ( ) . write_bytes ( 1 , size) ;
172
- libc:: free ( ptr) ;
173
- }
164
+ // Align > size.
165
+ unsafe {
166
+ let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
167
+ let align = 64 ;
168
+ let size = 8 ;
169
+ assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
170
+ assert ! ( !ptr. is_null( ) ) ;
171
+ assert ! ( ptr. is_aligned_to( align) ) ;
172
+ ptr. cast :: < u8 > ( ) . write_bytes ( 1 , size) ;
173
+ libc:: free ( ptr) ;
174
+ }
174
175
175
- // Size not multiple of align
176
- unsafe {
177
- let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
178
- let align = 16 ;
179
- let size = 31 ;
180
- assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
181
- assert ! ( !ptr. is_null( ) ) ;
182
- assert ! ( ptr. is_aligned_to( align) ) ;
183
- ptr. cast :: < u8 > ( ) . write_bytes ( 1 , size) ;
184
- libc:: free ( ptr) ;
185
- }
176
+ // Size not multiple of align
177
+ unsafe {
178
+ let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
179
+ let align = 16 ;
180
+ let size = 31 ;
181
+ assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
182
+ assert ! ( !ptr. is_null( ) ) ;
183
+ assert ! ( ptr. is_aligned_to( align) ) ;
184
+ ptr. cast :: < u8 > ( ) . write_bytes ( 1 , size) ;
185
+ libc:: free ( ptr) ;
186
+ }
186
187
187
- // Size == 0
188
- unsafe {
189
- let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
190
- let align = 64 ;
191
- let size = 0 ;
192
- assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
193
- // Non-null pointer is returned if size == 0.
194
- // (This is not a guarantee, it just reflects our current behavior.)
195
- assert ! ( !ptr. is_null( ) ) ;
196
- assert ! ( ptr. is_aligned_to( align) ) ;
197
- libc:: free ( ptr) ;
188
+ // Size == 0
189
+ unsafe {
190
+ let mut ptr: * mut libc:: c_void = ptr:: null_mut ( ) ;
191
+ let align = 64 ;
192
+ let size = 0 ;
193
+ assert_eq ! ( libc:: posix_memalign( & mut ptr, align, size) , 0 ) ;
194
+ // Non-null pointer is returned if size == 0.
195
+ // (This is not a guarantee, it just reflects our current behavior.)
196
+ assert ! ( !ptr. is_null( ) ) ;
197
+ assert ! ( ptr. is_aligned_to( align) ) ;
198
+ libc:: free ( ptr) ;
199
+ }
198
200
}
199
201
200
202
// Non-power of 2 align
@@ -241,6 +243,44 @@ fn test_reallocarray() {
241
243
}
242
244
}
243
245
246
+ #[ cfg( not( target_os = "windows" ) ) ]
247
+ fn test_aligned_alloc ( ) {
248
+ // libc doesn't have this function (https://github.com/rust-lang/libc/issues/3689),
249
+ // so we declare it ourselves.
250
+ extern "C" {
251
+ fn aligned_alloc ( alignment : libc:: size_t , size : libc:: size_t ) -> * mut libc:: c_void ;
252
+ }
253
+ // size not a multiple of the alignment
254
+ unsafe {
255
+ let p = aligned_alloc ( 16 , 3 ) ;
256
+ assert_eq ! ( p, ptr:: null_mut( ) ) ;
257
+ }
258
+
259
+ // alignment not power of 2
260
+ unsafe {
261
+ let p = aligned_alloc ( 63 , 8 ) ;
262
+ assert_eq ! ( p, ptr:: null_mut( ) ) ;
263
+ }
264
+
265
+ // repeated tests on correct alignment/size
266
+ for _ in 0 ..16 {
267
+ // alignment 1, size 4 should succeed and actually must align to 4 (because C says so...)
268
+ unsafe {
269
+ let p = aligned_alloc ( 1 , 4 ) ;
270
+ assert ! ( !p. is_null( ) ) ;
271
+ assert ! ( p. is_aligned_to( 4 ) ) ;
272
+ libc:: free ( p) ;
273
+ }
274
+
275
+ unsafe {
276
+ let p = aligned_alloc ( 64 , 64 ) ;
277
+ assert ! ( !p. is_null( ) ) ;
278
+ assert ! ( p. is_aligned_to( 64 ) ) ;
279
+ libc:: free ( p) ;
280
+ }
281
+ }
282
+ }
283
+
244
284
fn main ( ) {
245
285
test_malloc ( ) ;
246
286
test_calloc ( ) ;
@@ -254,6 +294,8 @@ fn main() {
254
294
target_os = "wasi" ,
255
295
) ) ) ]
256
296
test_reallocarray ( ) ;
297
+ #[ cfg( not( target_os = "windows" ) ) ]
298
+ test_aligned_alloc ( ) ;
257
299
258
300
test_memcpy ( ) ;
259
301
test_strcpy ( ) ;
0 commit comments