rust: adapt alloc
crate to the kernel
This customizes the subset of the Rust standard library `alloc` that was just imported as-is, mainly by: - Adding SPDX license identifiers. - Skipping modules (e.g. `rc` and `sync`) via new `cfg`s. - Adding fallible (`try_*`) versions of existing infallible methods (i.e. returning a `Result` instead of panicking). Since the standard library requires stable/unstable attributes, these additions are annotated with: #[stable(feature = "kernel", since = "1.0.0")] Using "kernel" as the feature allows to have the additions clearly marked. The "1.0.0" version is just a placeholder. (At the moment, only one is needed, but in the future more fallible methods will be added). Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Co-developed-by: Gary Guo <gary@garyguo.net> Signed-off-by: Gary Guo <gary@garyguo.net> Co-developed-by: Matthew Bakhtiari <dev@mtbk.me> Signed-off-by: Matthew Bakhtiari <dev@mtbk.me> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
753dece88d
commit
057b8d2571
33
rust/alloc/README.md
Normal file
33
rust/alloc/README.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# `alloc`
|
||||||
|
|
||||||
|
These source files come from the Rust standard library, hosted in
|
||||||
|
the <https://github.com/rust-lang/rust> repository, licensed under
|
||||||
|
"Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
|
||||||
|
see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
|
||||||
|
|
||||||
|
Please note that these files should be kept as close as possible to
|
||||||
|
upstream. In general, only additions should be performed (e.g. new
|
||||||
|
methods). Eventually, changes should make it into upstream so that,
|
||||||
|
at some point, this fork can be dropped from the kernel tree.
|
||||||
|
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
On one hand, kernel folks wanted to keep `alloc` in-tree to have more
|
||||||
|
freedom in both workflow and actual features if actually needed
|
||||||
|
(e.g. receiver types if we ended up using them), which is reasonable.
|
||||||
|
|
||||||
|
On the other hand, Rust folks wanted to keep `alloc` as close as
|
||||||
|
upstream as possible and avoid as much divergence as possible, which
|
||||||
|
is also reasonable.
|
||||||
|
|
||||||
|
We agreed on a middle-ground: we would keep a subset of `alloc`
|
||||||
|
in-tree that would be as small and as close as possible to upstream.
|
||||||
|
Then, upstream can start adding the functions that we add to `alloc`
|
||||||
|
etc., until we reach a point where the kernel already knows exactly
|
||||||
|
what it needs in `alloc` and all the new methods are merged into
|
||||||
|
upstream, so that we can drop `alloc` from the kernel tree and go back
|
||||||
|
to using the upstream one.
|
||||||
|
|
||||||
|
By doing this, the kernel can go a bit faster now, and Rust can
|
||||||
|
slowly incorporate and discuss the changes as needed.
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
//! Memory allocation APIs
|
//! Memory allocation APIs
|
||||||
|
|
||||||
#![stable(feature = "alloc_module", since = "1.28.0")]
|
#![stable(feature = "alloc_module", since = "1.28.0")]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
//! A module for working with borrowed data.
|
//! A module for working with borrowed data.
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -11,7 +13,7 @@ use core::ops::{Add, AddAssign};
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::borrow::{Borrow, BorrowMut};
|
pub use core::borrow::{Borrow, BorrowMut};
|
||||||
|
|
||||||
use crate::fmt;
|
use core::fmt;
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use crate::string::String;
|
use crate::string::String;
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
//! A pointer type for heap allocation.
|
//! A pointer type for heap allocation.
|
||||||
//!
|
//!
|
||||||
//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
|
//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
|
||||||
@ -163,9 +165,11 @@ use crate::str::from_boxed_utf8_unchecked;
|
|||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use crate::vec::Vec;
|
use crate::vec::Vec;
|
||||||
|
|
||||||
|
#[cfg(not(no_thin))]
|
||||||
#[unstable(feature = "thin_box", issue = "92791")]
|
#[unstable(feature = "thin_box", issue = "92791")]
|
||||||
pub use thin::ThinBox;
|
pub use thin::ThinBox;
|
||||||
|
|
||||||
|
#[cfg(not(no_thin))]
|
||||||
mod thin;
|
mod thin;
|
||||||
|
|
||||||
/// A pointer type for heap allocation.
|
/// A pointer type for heap allocation.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
//! Collection types.
|
//! Collection types.
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
//! # The Rust core allocation and collections library
|
//! # The Rust core allocation and collections library
|
||||||
//!
|
//!
|
||||||
//! This library provides smart pointers and collections for managing
|
//! This library provides smart pointers and collections for managing
|
||||||
@ -192,6 +194,7 @@ extern crate std;
|
|||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
// Module with internal macros used by other modules (needs to be included before other modules).
|
// Module with internal macros used by other modules (needs to be included before other modules).
|
||||||
|
#[cfg(not(no_macros))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
@ -216,11 +219,16 @@ pub mod borrow;
|
|||||||
pub mod collections;
|
pub mod collections;
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
|
#[cfg(not(no_fmt))]
|
||||||
pub mod fmt;
|
pub mod fmt;
|
||||||
|
#[cfg(not(no_rc))]
|
||||||
pub mod rc;
|
pub mod rc;
|
||||||
pub mod slice;
|
pub mod slice;
|
||||||
|
#[cfg(not(no_str))]
|
||||||
pub mod str;
|
pub mod str;
|
||||||
|
#[cfg(not(no_string))]
|
||||||
pub mod string;
|
pub mod string;
|
||||||
|
#[cfg(not(no_sync))]
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
#[cfg(all(not(no_global_oom_handling), target_has_atomic = "ptr"))]
|
#[cfg(all(not(no_global_oom_handling), target_has_atomic = "ptr"))]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
#![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")]
|
#![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")]
|
||||||
|
|
||||||
use core::alloc::LayoutError;
|
use core::alloc::LayoutError;
|
||||||
@ -307,6 +309,12 @@ impl<T, A: Allocator> RawVec<T, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The same as `reserve_for_push`, but returns on errors instead of panicking or aborting.
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn try_reserve_for_push(&mut self, len: usize) -> Result<(), TryReserveError> {
|
||||||
|
self.grow_amortized(len, 1)
|
||||||
|
}
|
||||||
|
|
||||||
/// Ensures that the buffer contains at least enough space to hold `len +
|
/// Ensures that the buffer contains at least enough space to hold `len +
|
||||||
/// additional` elements. If it doesn't already, will reallocate the
|
/// additional` elements. If it doesn't already, will reallocate the
|
||||||
/// minimum possible amount of memory necessary. Generally this will be
|
/// minimum possible amount of memory necessary. Generally this will be
|
||||||
@ -421,6 +429,7 @@ impl<T, A: Allocator> RawVec<T, A> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
|
fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
|
||||||
assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
|
assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
//! A dynamically-sized view into a contiguous sequence, `[T]`.
|
//! A dynamically-sized view into a contiguous sequence, `[T]`.
|
||||||
//!
|
//!
|
||||||
//! *[See also the slice primitive type](slice).*
|
//! *[See also the slice primitive type](slice).*
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
use crate::alloc::{Allocator, Global};
|
use crate::alloc::{Allocator, Global};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::iter::{FusedIterator, TrustedLen};
|
use core::iter::{FusedIterator, TrustedLen};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
use crate::alloc::{Allocator, Global};
|
use crate::alloc::{Allocator, Global};
|
||||||
use core::ptr::{self};
|
use core::ptr::{self};
|
||||||
use core::slice::{self};
|
use core::slice::{self};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use super::AsVecIntoIter;
|
use super::AsVecIntoIter;
|
||||||
use crate::alloc::{Allocator, Global};
|
use crate::alloc::{Allocator, Global};
|
||||||
@ -9,6 +11,7 @@ use core::iter::{
|
|||||||
};
|
};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::{self, ManuallyDrop};
|
use core::mem::{self, ManuallyDrop};
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use core::ptr::{self, NonNull};
|
use core::ptr::{self, NonNull};
|
||||||
use core::slice::{self};
|
use core::slice::{self};
|
||||||
@ -123,6 +126,7 @@ impl<T, A: Allocator> IntoIter<T, A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed.
|
/// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn forget_remaining_elements(&mut self) {
|
pub(crate) fn forget_remaining_elements(&mut self) {
|
||||||
self.ptr = self.end;
|
self.ptr = self.end;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
use crate::boxed::Box;
|
use crate::boxed::Box;
|
||||||
|
|
||||||
#[rustc_specialization_trait]
|
#[rustc_specialization_trait]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
//! A contiguous growable array type with heap-allocated contents, written
|
//! A contiguous growable array type with heap-allocated contents, written
|
||||||
//! `Vec<T>`.
|
//! `Vec<T>`.
|
||||||
//!
|
//!
|
||||||
@ -1739,6 +1741,29 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tries to append an element to the back of a collection.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut vec = vec![1, 2];
|
||||||
|
/// vec.try_push(3).unwrap();
|
||||||
|
/// assert_eq!(vec, [1, 2, 3]);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[stable(feature = "kernel", since = "1.0.0")]
|
||||||
|
pub fn try_push(&mut self, value: T) -> Result<(), TryReserveError> {
|
||||||
|
if self.len == self.buf.capacity() {
|
||||||
|
self.buf.try_reserve_for_push(self.len)?;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
let end = self.as_mut_ptr().add(self.len);
|
||||||
|
ptr::write(end, value);
|
||||||
|
self.len += 1;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Removes the last element from a vector and returns it, or [`None`] if it
|
/// Removes the last element from a vector and returns it, or [`None`] if it
|
||||||
/// is empty.
|
/// is empty.
|
||||||
///
|
///
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
|
||||||
use crate::alloc::Allocator;
|
use crate::alloc::Allocator;
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use crate::borrow::Cow;
|
use crate::borrow::Cow;
|
||||||
|
Loading…
Reference in New Issue
Block a user