Skip to content

Commit 7392c80

Browse files
CoAlloc: Preference/config types in ::alloc::co_alloc. Config value macros + transformation macros in ::alloc. WIP (won't compile).
1 parent 9ca4c8e commit 7392c80

File tree

4 files changed

+216
-143
lines changed

4 files changed

+216
-143
lines changed

library/alloc/src/co_alloc.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//! CoAlloction-specific types that only apply in heap-based applications (hence not a part of
2+
//! [::core]).
3+
//!
4+
//! Types here have names with `CoAlloc` prefix. Yes, when using a q ualified path (like
5+
//! ::alloc::co_alloc::CoAllocPref), that involves "stuttering", which is not recommended.
6+
//!
7+
//! However, as per Rust Book the common practice is to import type names fully and access them just
8+
//! with their name (except for cases of conflict). And we don't want the type names any shorter
9+
//! (such `Pref`), because thoe would be vague/confusing.
10+
11+
/// `CoAllocPref` values indicate a type's preference for coallocation (in either user space, or
12+
/// `std` space). Used as a `const` generic parameter type (usually called `CO_ALLOC_PREF`).
13+
///
14+
/// The actual value may be overriden by the allocator. See also `CoAllocMetaNumSlotsPref` and
15+
/// `co_alloc_pref` macro .
16+
///
17+
/// This type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
18+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence:
19+
/// - DO NOT construct instances, but use `co_alloc_pref` macro together with constants
20+
/// `CO_ALLOC_PREF_META_YES` and `CO_ALLOC_PREF_META_NO`;
21+
/// - DO NOT hard code any values; and
22+
/// - DO NOT mix this/cast this with/to `u8`, `u16`, `usize` (nor any other integer).
23+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
24+
pub type CoAllocPref = u8;
25+
26+
/// `CoAllocMetaNumSlotsPref` values indicate a type (but not an allocator) prefers to coallocate by
27+
/// carrying metadata, or not. (In either user space, or `std` space). Used as an argument to macro
28+
/// call of `co_alloc_pref`, which generates a `CoAllocPref` value.
29+
///
30+
/// Currently this indicates only the (preferred) number of `CoAllocMetaBase` slots being used
31+
/// (either 1 = coallocation, or 0 = no coallocation). However, in the future this type may have
32+
/// other properties (serving as extra hints to the allocator).
33+
///
34+
/// The actual value may be overriden by the allocator. For example, if the allocator doesn't
35+
/// support coallocation, then whether this value prefers to coallocate or not makes no difference.
36+
///
37+
/// This type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
38+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence:
39+
/// - DO NOT mix this/cast this with/to `u8`, `u16`, (nor any other integer); and
40+
/// - DO NOT hard code any values, but use `CO_ALLOC_PREF_META_YES` and `CO_ALLOC_PREF_META_NO`.
41+
///
42+
/// This type is intentionally not `u16`, `u32`, nor `usize`. Why? This helps to prevent mistakes
43+
/// when one would use `CO_ALLOC_PREF_META_YES` or `CO_ALLOC_PREF_META_NO` in place of `CoAllocPref`
44+
/// vales, or in place of a result of `meta_num_slots` macro. That also prevents mixing up with
45+
/// [core::alloc::CoAllocatorMetaNumSlots].
46+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
47+
pub type CoAllocMetaNumSlotsPref = u16;

library/alloc/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ mod boxed {
249249
pub use std::boxed::Box;
250250
}
251251
pub mod borrow;
252+
#[unstable(feature = "global_co_alloc", issue = "none")]
253+
pub mod co_alloc;
252254
pub mod collections;
253255
#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
254256
pub mod ffi;

library/alloc/src/macros.rs

Lines changed: 109 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -125,37 +125,113 @@ macro_rules! __rust_force_expr {
125125
};
126126
}
127127

128-
/// Default coallocation "cooperation" (`COOP_PREF`) generic parameter.
128+
// ----- CoAlloc constant-like macros:
129+
/// "Yes" as a type's preference for coallocation (in either user space, or `std` space).
129130
///
130-
/// NOT for public use. It's exported only so that library/proc_macro (and other internals) can use
131-
/// this.
131+
/// It may be overriden by the allocator. For example, if the allocator doesn't support
132+
/// coallocation, then this value makes no difference.
132133
///
133-
// FIXME replace with a `const` (or some kind of compile time preference) once a related ICE is
134-
// fixed. Then move the const to a submodule, for example alloc::co_alloc.
134+
/// This constant and its type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
135+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence DO NOT hard
136+
/// code/replace/mix this any other values/parameters.
137+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
138+
#[macro_export]
139+
macro_rules! CO_ALLOC_PREF_META_YES {
140+
() => {
141+
(1 as $crate::co_alloc::CoAllocMetaNumSlotsPref)
142+
};
143+
}
144+
145+
/// "No" as a type's preference for coallocation (in either user space, or `std` space).
146+
///
147+
/// Any allocator is required to respect this. Even if the allocator does support coallocation, it
148+
/// will not coallocate types that use this value.
149+
///
150+
/// This constant and its type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
151+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence DO NOT hard
152+
/// code/replace/mix this any other values/parameters.
153+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
154+
#[macro_export]
155+
macro_rules! CO_ALLOC_PREF_META_NO {
156+
() => {
157+
(0 as $crate::co_alloc::CoAllocMetaNumSlotsPref)
158+
};
159+
}
160+
161+
/// Default preference for coallocation (in either user space, or `std` space).
162+
///
163+
/// Possible values are only: `CO_ALLOC_PREF_META_YES` and `CO_ALLOC_PREF_META_NO`. See their
164+
/// documentation.
165+
///
166+
/// This value and its type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
167+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence DO NOT hard
168+
/// code/replace/mix this any other values/parameters.
169+
///
170+
/// (@FIXME) This WILL BE BECOME OBSOLETE and it WILL BE REPLACED with a `const` (and/or some kind
171+
/// of compile time preference) once a related ICE is fixed (@FIXME add the ICE link here). Then
172+
/// consider moving such a `const` to a submodule, for example `::alloc::co_alloc`.
135173
#[unstable(feature = "global_co_alloc_default", issue = "none")]
136174
#[macro_export]
137-
macro_rules! CO_ALLOC_PREF_DEFAULT {
175+
macro_rules! CO_ALLOC_PREF_META_DEFAULT {
138176
() => {
139-
true
177+
(0 as $crate::co_alloc::CoAllocMetaNumSlotsPref)
178+
};
179+
}
180+
181+
/// Default [::alloc::CoAllocPref] value/config, based on `CO_ALLOC_PREF_META_DEFAULT`.
182+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
183+
#[macro_export]
184+
macro_rules! CO_ALLOC_PREF_DEFAULT {
185+
() => { $crate::co_alloc_pref!($crate::CO_ALLOC_PREF_META_DEFAULT!()) };
186+
}
187+
188+
// ------ CoAlloc preference/config conversion macros:
189+
/// Create a `CoAllocPref` value based on the given parameter(s). For now, only one parameter is
190+
/// supported, and it's required: `meta_pref`.
191+
///
192+
/// @param `meta_pref` is one of: `CO_ALLOC_PREF_META_YES, CO_ALLOC_PREF_META_NO,
193+
/// CO_ALLOC_PREF_META_DEFAULT`.
194+
///
195+
/// @return `CoAllocPref` value
196+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
197+
#[macro_export]
198+
macro_rules! co_alloc_pref {
199+
// ($meta_pref + (0 as CoAllocMetaNumSlotsPref)) ensures that $meta_pref is of type
200+
// `CoAllocMetaNumSlotsPref`. Otherwise the casting of the result to `CoAllocPref` would not
201+
// report the incorrect type of $meta_pref (if $meta_pref were some other integer, casting would
202+
// compile, and we would not be notified).
203+
($meta_pref:expr) => {
204+
(($meta_pref + (0 as $crate::co_alloc::CoAllocMetaNumSlotsPref)) as $crate::co_alloc::CoAllocPref)
140205
};
141206
}
142-
// -\---> replace with something like: pub const DEFAULT_COOP_PREF: bool = true;
143207

144208
/// Return 0 or 1, indicating whether to use coallocation metadata (or not) with the given allocator
145-
/// type `alloc` and cooperation preference `coop_pref`.
209+
/// type `alloc` and cooperation preference `co_alloc_pref`.
146210
///
147-
/// NOT for public use. Param `coop_pref` - can override the allocator's default preference for
211+
/// NOT for public use. Param `co_alloc_pref` - can override the allocator's default preference for
148212
/// cooperation, or can make the type not cooperative, regardless of whether allocator `A` is
149213
/// cooperative.
214+
///
215+
/// @param `alloc` Allocator (implementation) type. @param `co_alloc_pref` The heap-based type's
216+
/// preference for coallocation, as an [::alloc::CoAllocPref] value.
217+
///
218+
/// The type of second parameter `co_alloc_pref` WILL CHANGE. DO NOT hardcode/cast/mix that type.
219+
/// Instead, use [::alloc::CoAllocPref].
220+
///
150221
// FIXME replace the macro with an (updated version of the below) `const` function). Only once
151222
// generic_const_exprs is stable (that is, when consumer crates don't need to declare
152-
// generic_const_exprs feature anymore). Then move the function to a submodule, for example
153-
// ::alloc::co_alloc.
223+
// generic_const_exprs feature anymore). Then consider moving the function to a submodule, for
224+
// example ::alloc::co_alloc.
154225
#[unstable(feature = "global_co_alloc", issue = "none")]
155226
#[macro_export]
156227
macro_rules! meta_num_slots {
157-
($alloc:ty, $coop_pref:expr) => {
158-
if ($alloc::CO_ALLOC_META_NUM_SLOTS) && ($coop_pref) { 1 } else { 0 }
228+
// This "validates" types of both params - to prevent mix ups.
229+
($alloc:ty, $co_alloc_pref:expr) => {
230+
(
231+
((<$alloc>::CO_ALLOC_META_NUM_SLOTS + (0 as ::core::alloc::CoAllocatorMetaNumSlots))
232+
as $crate::co_alloc::CoAllocPref)
233+
* ($co_alloc_pref + (0 as $crate::co_alloc::CoAllocPref))
234+
as usize)
159235
};
160236
}
161237
// -\---> replace with something like:
@@ -171,46 +247,46 @@ pub const fn meta_num_slots<A: Allocator>(
171247
/// Like `meta_num_slots`, but for the default coallocation preference (`DEFAULT_COOP_PREF`).
172248
///
173249
/// Return 0 or 1, indicating whether to use coallocation metadata (or not) with the given allocator
174-
/// type `alloc` and the default cooperation preference (`DEFAULT_COOP_PREF()!`).
250+
/// type `alloc` and the default coallocation preference (`DEFAULT_COOP_PREF()!`).
175251
///
176-
/// NOT for public use.
177252
// FIXME replace the macro with a `const` function. Only once generic_const_exprs is stable (that
178-
// is, when consumer crates don't need to declare generic_const_exprs feature anymore). Then move
179-
// the function to a submodule, for example ::alloc::co_alloc.
253+
// is, when consumer crates don't need to declare generic_const_exprs feature anymore). Then
254+
// consider moving the function to a submodule, for example ::alloc::co_alloc.
180255
#[unstable(feature = "global_co_alloc", issue = "none")]
181256
#[macro_export]
182257
macro_rules! meta_num_slots_default {
183258
// Can't generate if ... {1} else {0}
184259
// because it's "overly complex generic constant".
185260
($alloc:ty) => {
186-
if (<$alloc>::CO_ALLOC_META_NUM_SLOTS) && (DEFAULT_COOP_PREF!()) { 1 } else { 0 }
261+
$crate::meta_num_slots!( $alloc, $crate::CO_ALLOC_PREF_DEFAULT!() )
187262
};
188263
}
189264

190-
/// NOT for public use.
191-
// See above.
265+
/// Like `meta_num_slots`, but for the default coallocation preference (`DEFAULT_COOP_PREF`).
266+
///
267+
/// Return 0 or 1, indicating whether to use coallocation metadata (or not) with the global allocator
268+
/// type `alloc` and the given coallocation preference `co_alloc_`.
269+
///
270+
// FIXME replace the macro with a `const` function. Only once generic_const_exprs is stable (that
271+
// is, when consumer crates don't need to declare `generic_const_exprs` feature anymore). Then
272+
// consider moving the function to a submodule, for example ::alloc::co_alloc. See above.
192273
#[unstable(feature = "global_co_alloc", issue = "none")]
193274
#[macro_export]
194275
macro_rules! meta_num_slots_global {
195-
($coop_pref:expr) => {
196-
if ::alloc::alloc::Global::CO_ALLOC_META_NUM_SLOTS && ($coop_pref) { 1 } else { 0 }
276+
($co_alloc_pref:expr) => {
277+
$crate::meta_num_slots!( $crate::alloc::Global, $co_alloc_pref)
197278
};
198279
}
199280

200-
/// Like `meta_num_slots`, but for Global allocator and default coallocation preference
201-
/// (`DEFAULT_COOP_PREF`).
281+
/// Like `meta_num_slots`, but for `Global allocator and default coallocation preference
282+
/// (`CO_ALLOC_PREF_DEFAULT`).
202283
///
203-
/// NOT for public use.
204-
// @FIXME once generic_const_exprs is stable, replace this with a `const` function. Then move the
205-
// function to a submodule, for example alloc::co_alloc. See above.
284+
// @FIXME once generic_const_exprs is stable, replace this with a `const` function. Then consider
285+
// moving the function to a submodule, for example alloc::co_alloc. See above.
206286
#[unstable(feature = "global_co_alloc", issue = "none")]
207287
#[macro_export]
208288
macro_rules! meta_num_slots_default_global {
209289
() => {
210-
if ::alloc::alloc::Global::CO_ALLOC_META_NUM_SLOTS && (DEFAULT_COOP_PREF!()) {
211-
1
212-
} else {
213-
0
214-
}
290+
$crate::meta_num_slots!( $crate::alloc::Global, $crate::CO_ALLOC_PREF_DEFAULT!())
215291
};
216292
}

0 commit comments

Comments
 (0)