@@ -316,25 +316,38 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
316
316
target_os = "solaris" ,
317
317
target_os = "illumos" ,
318
318
) ) ] {
319
+ #[ allow( unused_assignments) ]
320
+ #[ allow( unused_mut) ]
321
+ let mut quota = usize :: MAX ;
322
+
319
323
#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
320
324
{
321
- let quota = cgroups:: quota( ) . max( 1 ) ;
325
+ quota = cgroups:: quota( ) . max( 1 ) ;
322
326
let mut set: libc:: cpu_set_t = unsafe { mem:: zeroed( ) } ;
323
327
unsafe {
324
328
if libc:: sched_getaffinity( 0 , mem:: size_of:: <libc:: cpu_set_t>( ) , & mut set) == 0 {
325
329
let count = libc:: CPU_COUNT ( & set) as usize ;
326
330
let count = count. min( quota) ;
327
- // reported to occur on MIPS kernels older than our minimum supported kernel version for those targets
328
- let count = NonZeroUsize :: new( count)
329
- . expect( "CPU count must be > 0. This may be a bug in sched_getaffinity(); try upgrading the kernel." ) ;
330
- return Ok ( count) ;
331
+
332
+ // According to sched_getaffinity's API it should always be non-zero, but
333
+ // some old MIPS kernels were buggy and zero-initialized the mask if
334
+ // none was explicitly set.
335
+ // In that case we use the sysconf fallback.
336
+ if let Some ( count) = NonZeroUsize :: new( count) {
337
+ return Ok ( count)
338
+ }
331
339
}
332
340
}
333
341
}
334
342
match unsafe { libc:: sysconf( libc:: _SC_NPROCESSORS_ONLN) } {
335
343
-1 => Err ( io:: Error :: last_os_error( ) ) ,
336
344
0 => Err ( io:: const_io_error!( io:: ErrorKind :: NotFound , "The number of hardware threads is not known for the target platform" ) ) ,
337
- cpus => Ok ( unsafe { NonZeroUsize :: new_unchecked( cpus as usize ) } ) ,
345
+ cpus => {
346
+ let count = cpus as usize ;
347
+ // Cover the unusual situation where we were able to get the quota but not the affinity mask
348
+ let count = count. min( quota) ;
349
+ Ok ( unsafe { NonZeroUsize :: new_unchecked( count) } )
350
+ }
338
351
}
339
352
} else if #[ cfg( any( target_os = "freebsd" , target_os = "dragonfly" , target_os = "netbsd" ) ) ] {
340
353
use crate :: ptr;
0 commit comments