Skip to content
This repository was archived by the owner on Nov 27, 2020. It is now read-only.

Commit 3356d39

Browse files
committed
Deprecate free-standing allocation methods
1 parent e47c919 commit 3356d39

File tree

2 files changed

+151
-22
lines changed

2 files changed

+151
-22
lines changed

src/alloc/mod.rs

Lines changed: 150 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,139 @@ pub use core::alloc::GlobalAlloc;
55
use core::{
66
cmp,
77
fmt,
8+
intrinsics::likely,
89
num::NonZeroUsize,
910
ptr::{self, NonNull},
1011
};
11-
pub use liballoc::alloc::{alloc, alloc_zeroed, dealloc, handle_alloc_error, realloc, Layout};
12+
pub use liballoc::alloc::Layout;
1213
#[cfg(feature = "std")]
1314
use std::alloc::System;
1415

16+
/// Abort on memory allocation error or failure.
17+
///
18+
/// Callers of memory allocation APIs wishing to abort computation
19+
/// in response to an allocation error are encouraged to call this function,
20+
/// rather than directly invoking `panic!` or similar.
21+
///
22+
/// The default behavior of this function is to print a message to standard error
23+
/// and abort the process.
24+
/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
25+
///
26+
/// [`set_alloc_error_hook`]: https://doc.rust-lang.org/nightly/std/alloc/fn.set_alloc_error_hook.html
27+
/// [`take_alloc_error_hook`]: https://doc.rust-lang.org/nightly/std/alloc/fn.take_alloc_error_hook.html
28+
#[allow(clippy::inline_always)]
29+
#[inline(always)]
30+
#[deprecated = "allocation functions returns an error, use that instead"]
31+
pub fn handle_alloc_error(layout: Layout) -> ! {
32+
liballoc::alloc::handle_alloc_error(layout)
33+
}
34+
35+
/// Allocate memory with the global allocator.
36+
///
37+
/// This function forwards calls to the [`GlobalAlloc::alloc`] method
38+
/// of the allocator registered with the `#[global_allocator]` attribute
39+
/// if there is one, or the `std` crate’s default.
40+
///
41+
/// # Safety
42+
///
43+
/// See [`GlobalAlloc::alloc`].
44+
///
45+
/// [`GlobalAlloc::alloc`]: GlobalAlloc::alloc
46+
///
47+
/// # Examples
48+
///
49+
/// ```
50+
/// use alloc_wg::alloc::{alloc, dealloc, Layout};
51+
///
52+
/// unsafe {
53+
/// let layout = Layout::new::<u16>();
54+
/// let ptr = alloc(layout);
55+
///
56+
/// *(ptr as *mut u16) = 42;
57+
/// assert_eq!(*(ptr as *mut u16), 42);
58+
///
59+
/// dealloc(ptr, layout);
60+
/// }
61+
/// ```
62+
#[allow(clippy::inline_always)]
63+
#[inline(always)]
64+
#[must_use = "allocating is expected to be expensive"]
65+
#[deprecated = "Use `Global::alloc` instead"]
66+
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
67+
liballoc::alloc::alloc(layout)
68+
}
69+
70+
/// Deallocate memory with the global allocator.
71+
///
72+
/// This function forwards calls to the [`GlobalAlloc::dealloc`] method
73+
/// of the allocator registered with the `#[global_allocator]` attribute
74+
/// if there is one, or the `std` crate’s default.
75+
///
76+
/// # Safety
77+
///
78+
/// See [`GlobalAlloc::dealloc`].
79+
///
80+
/// [`GlobalAlloc::dealloc`]: GlobalAlloc::dealloc
81+
#[allow(clippy::inline_always)]
82+
#[inline(always)]
83+
#[deprecated = "Use `Global::dealloc` instead"]
84+
pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
85+
liballoc::alloc::dealloc(ptr, layout)
86+
}
87+
88+
/// Reallocate memory with the global allocator.
89+
///
90+
/// This function forwards calls to the [`GlobalAlloc::realloc`] method
91+
/// of the allocator registered with the `#[global_allocator]` attribute
92+
/// if there is one, or the `std` crate’s default.
93+
///
94+
/// # Safety
95+
///
96+
/// See [`GlobalAlloc::realloc`].
97+
///
98+
/// [`GlobalAlloc::realloc`]: GlobalAlloc::realloc
99+
#[allow(clippy::inline_always)]
100+
#[inline(always)]
101+
#[must_use = "reallocating is expected to be expensive"]
102+
#[deprecated = "Use `Global::realloc` instead"]
103+
pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
104+
liballoc::alloc::realloc(ptr, layout, new_size)
105+
}
106+
107+
/// Allocate zero-initialized memory with the global allocator.
108+
///
109+
/// This function forwards calls to the [`GlobalAlloc::alloc_zeroed`] method
110+
/// of the allocator registered with the `#[global_allocator]` attribute
111+
/// if there is one, or the `std` crate’s default.
112+
///
113+
/// # Safety
114+
///
115+
/// See [`GlobalAlloc::alloc_zeroed`].
116+
///
117+
/// [`GlobalAlloc::alloc_zeroed`]: GlobalAlloc::alloc_zeroed
118+
///
119+
/// # Examples
120+
///
121+
/// ```
122+
/// use alloc_wg::alloc::{alloc_zeroed, dealloc, Layout};
123+
///
124+
/// unsafe {
125+
/// let layout = Layout::new::<u16>();
126+
/// let ptr = alloc_zeroed(layout);
127+
///
128+
/// assert_eq!(*(ptr as *mut u16), 0);
129+
///
130+
/// dealloc(ptr, layout);
131+
/// }
132+
/// ```
133+
#[allow(clippy::inline_always)]
134+
#[inline(always)]
135+
#[must_use = "allocating is expected to be expensive"]
136+
#[deprecated = "Use `Global::alloc_zeroed` instead"]
137+
pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
138+
liballoc::alloc::alloc_zeroed(layout)
139+
}
140+
15141
#[derive(Clone, PartialEq, Eq, Debug)]
16142
pub struct CapacityOverflow;
17143

@@ -212,6 +338,7 @@ impl DeallocRef for Global {
212338
}
213339

214340
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: NonZeroLayout) {
341+
#[allow(deprecated)]
215342
dealloc(ptr.as_ptr(), layout.into())
216343
}
217344
}
@@ -220,23 +347,31 @@ impl AllocRef for Global {
220347
type Error = AllocErr;
221348

222349
fn alloc(&mut self, layout: NonZeroLayout) -> Result<NonNull<u8>, Self::Error> {
223-
unsafe { NonNull::new(alloc(layout.into())).ok_or(AllocErr) }
350+
#[allow(deprecated)]
351+
unsafe {
352+
NonNull::new(alloc(layout.into())).ok_or(AllocErr)
353+
}
224354
}
225355

226356
fn alloc_zeroed(&mut self, layout: NonZeroLayout) -> Result<NonNull<u8>, Self::Error> {
227-
unsafe { NonNull::new(alloc_zeroed(layout.into())).ok_or(AllocErr) }
357+
#[allow(deprecated)]
358+
unsafe {
359+
NonNull::new(alloc_zeroed(layout.into())).ok_or(AllocErr)
360+
}
228361
}
229362
}
230363

231364
impl ReallocRef for Global {
365+
// FIXME: Remove `else` branch. This is needed, as std provides old method.
232366
unsafe fn realloc(
233367
&mut self,
234368
ptr: NonNull<u8>,
235369
old_layout: NonZeroLayout,
236370
new_layout: NonZeroLayout,
237371
) -> Result<NonNull<u8>, Self::Error> {
238-
// FIXME: Remove `else` branch. This is needed, as std provides old method.
239-
if old_layout.align() == new_layout.align() {
372+
// TODO: Test if this is a well suited case for `likely`
373+
if likely(old_layout.align() == new_layout.align()) {
374+
#[allow(deprecated)]
240375
NonNull::new(realloc(
241376
ptr.as_ptr(),
242377
old_layout.into(),
@@ -284,7 +419,8 @@ impl ReallocRef for System {
284419
old_layout: NonZeroLayout,
285420
new_layout: NonZeroLayout,
286421
) -> Result<NonNull<u8>, Self::Error> {
287-
if old_layout.align() == new_layout.align() {
422+
// TODO: Test if this is a well suited case for `likely`
423+
if likely(old_layout.align() == new_layout.align()) {
288424
NonNull::new(GlobalAlloc::realloc(
289425
self,
290426
ptr.as_ptr(),
@@ -305,15 +441,12 @@ unsafe fn alloc_copy_dealloc<A: ReallocRef>(
305441
old_layout: NonZeroLayout,
306442
new_layout: NonZeroLayout,
307443
) -> Result<NonNull<u8>, A::Error> {
308-
let result = alloc.alloc(new_layout);
309-
310-
if let Ok(new_ptr) = result {
311-
ptr::copy_nonoverlapping(
312-
ptr.as_ptr(),
313-
new_ptr.as_ptr(),
314-
cmp::min(old_layout.size().get(), new_layout.size().get()),
315-
);
316-
alloc.dealloc(ptr, old_layout);
317-
}
318-
result
444+
let new_ptr = alloc.alloc(new_layout)?;
445+
ptr::copy_nonoverlapping(
446+
ptr.as_ptr(),
447+
new_ptr.as_ptr(),
448+
cmp::min(old_layout.size().get(), new_layout.size().get()),
449+
);
450+
alloc.dealloc(ptr, old_layout);
451+
Ok(new_ptr)
319452
}

src/lib.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@
2323
//!
2424
//! - Added an associative error type to [`AllocRef`]. Besides adding the possibility of returning additional information on
2525
//! allocation failure, it's also possible to split the usage of the [`AllocRef`] into a fallible and an infallible case.
26-
//! Personally I think this is a pretty big deal, as kernel programmer can rely on allocation, which will never fail. If
27-
//! an allocation can fail, only a `try_*_in` method may be available. To maintain backwards compatibility, [`AbortAlloc`]
28-
//! was introduced. [`AbortAlloc`] wraps another allocator, but aborts on OOM thus `AbortAlloc<Global>` may be used as
29-
//! default allocator for [`Box`] or `Vec`. To realize this, [`AbortAlloc`] implements `AllocRef<Error=!>`.
26+
//! Personally I think this is a pretty big deal, as kernel programmer can rely on allocation, which will never fail.
3027
//!
3128
//! Issue: [rust-lang/wg-allocators#23](https://github.com/rust-lang/wg-allocators/issues/23)
3229
//!
@@ -53,7 +50,6 @@
5350
//! [`BuildHasher`]: https://doc.rust-lang.org/1.38.0/core/hash/trait.BuildHasher.html
5451
//! [`Hasher`]: https://doc.rust-lang.org/1.38.0/core/hash/trait.Hasher.html
5552
//! [`NonZeroLayout`]: crate::alloc::NonZeroLayout
56-
//! [`AbortAlloc`]: crate::alloc::AbortAlloc
5753
5854
#![feature(
5955
dropck_eyepatch,

0 commit comments

Comments
 (0)