Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,38 @@ unsafe extern "Rust" {
fn __rust_no_alloc_shim_is_unstable_v2();
}

/// The global memory allocator.
/// A wrapper for the global allocator.
///
/// This type implements the [`Allocator`] trait by forwarding calls
/// to the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
///
/// `Global` is not "the global allocator", but a wrapper for it.
/// If the global allocator used `Global`, it would call itself recursively.
/// To avoid this, `Global` does not implement [`GlobalAlloc`].
///
/// Similar to [`alloc`], [`dealloc`], and the other global allocation functions,
/// the way in which calls are forwarded to the allocator registered with
/// when and how calls are forwarded to the allocator registered with
/// `#[global_allocator]` is unspecified. See their safety docs for more information.
///
/// This allocator must be treated like an opaque allocator that only guarantees
/// the contract described in the docs of [`Allocator`], as well as the following
/// things:
/// In particular, even if you know which allocator was registered
/// as the global allocator, calling it directly is not the same as calling
/// `Global`. You cannot deallocate memory from one using the other.
///
/// `Global` must be treated like an opaque allocator that only guarantees the contract
/// described in the docs of [`Allocator`], as well as the following:
/// * All instances of `Global` are [*equivalent*].
/// * Allocations from `Global` are only invalidated by calls to de-/reallocating functions.
/// If no such call is made, then the allocation will live for the rest of the program.
/// * The global allocation functions are equivalent to the methods on `Global`, except
/// that they disallow zero-sized allocations, and implicitly ignore any returned
/// excess size.
/// * The global allocation functions in the [`alloc`](self) module are equivalent to the
/// methods on `Global`, except that they disallow zero-sized allocations, and implicitly
/// ignore any returned excess size.
/// In particular, you may deallocate memory from [`alloc::alloc`](self::alloc) using
/// [`Global.deallocate`](Global::deallocate) and vice-versa.
///
/// Note that the current implementation of `Global` does not take advantage of
/// some features of [`Allocator`], such as zero-sized allocations (which currently always
/// some features of [`Allocator`], such as zero-sized allocations (which currently
/// return a dangling pointer) and overallocating.
///
/// This may change in the future. You must not rely on it for correctness!
///
/// [*equivalent*]: Allocator#equivalent-allocators
Expand Down
40 changes: 28 additions & 12 deletions library/std/src/sys/thread/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
target_os = "hurd",
target_os = "linux",
target_os = "aix",
target_os = "freebsd",
target_vendor = "apple",
target_os = "cygwin",
target_os = "redox",
Expand All @@ -175,17 +174,9 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
#[cfg(any(target_os = "android", target_os = "linux"))]
{
quota = cgroups::quota().max(1);
}

#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
{
#[cfg(not(target_os = "freebsd"))]
type Cpuset = libc::cpu_set_t;
#[cfg(target_os = "freebsd")]
type Cpuset = libc::cpuset_t;
let mut set: Cpuset = unsafe { mem::zeroed() };
let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
unsafe {
if libc::sched_getaffinity(0, size_of::<Cpuset>(), &mut set) == 0 {
if libc::sched_getaffinity(0, size_of::<libc::cpu_set_t>(), &mut set) == 0 {
let count = libc::CPU_COUNT(&set) as usize;
let count = count.min(quota);

Expand All @@ -210,9 +201,34 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
}
}
}
any(target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd") => {
any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd",
target_os = "netbsd",
) => {
use crate::ptr;

#[cfg(target_os = "freebsd")]
{
let mut set: libc::cpuset_t = unsafe { mem::zeroed() };
unsafe {
if libc::cpuset_getaffinity(
libc::CPU_LEVEL_WHICH,
libc::CPU_WHICH_PID,
-1,
size_of::<libc::cpuset_t>(),
&mut set,
) == 0
{
let count = libc::CPU_COUNT(&set) as usize;
if count > 0 {
return Ok(NonZero::new_unchecked(count));
}
}
}
}

#[cfg(target_os = "netbsd")]
{
unsafe {
Expand Down
Loading
Loading