Skip to content

Commit 37c55a3

Browse files
CoAlloc: meta_num_slots... macros- WIP..
1 parent e8d7dbd commit 37c55a3

File tree

3 files changed

+106
-19
lines changed

3 files changed

+106
-19
lines changed

library/alloc/src/macros.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ macro_rules! DEFAULT_COOP_PREF {
155155
#[macro_export]
156156
macro_rules! meta_num_slots {
157157
($alloc:ty, $coop_pref:expr) => {
158-
if ($alloc::CO_ALLOCATES_WITH_META) && ($coop_pref) { 1 } else { 0 }
158+
if ($alloc::CO_ALLOC_META_NUM_SLOTS) && ($coop_pref) { 1 } else { 0 }
159159
};
160160
}
161161
// -\---> replace with something like:
@@ -164,7 +164,7 @@ macro_rules! meta_num_slots {
164164
pub const fn meta_num_slots<A: Allocator>(
165165
COOP_PREF: bool,
166166
) -> usize {
167-
if A::CO_ALLOCATES_WITH_META && COOP_PREF { 1 } else { 0 }
167+
if A::CO_ALLOC_META_NUM_SLOTS && COOP_PREF { 1 } else { 0 }
168168
}
169169
*/
170170

@@ -180,8 +180,10 @@ pub const fn meta_num_slots<A: Allocator>(
180180
#[unstable(feature = "global_co_alloc", issue = "none")]
181181
#[macro_export]
182182
macro_rules! meta_num_slots_default {
183+
// Can't generate if ... {1} else {0}
184+
// because it's "overly complex generic constant".
183185
($alloc:ty) => {
184-
if ($alloc::CO_ALLOCATES_WITH_META) && (DEFAULT_COOP_PREF!()) { 1 } else { 0 }
186+
if (<$alloc>::CO_ALLOC_META_NUM_SLOTS) && (DEFAULT_COOP_PREF!()) { 1 } else { 0 }
185187
};
186188
}
187189

@@ -191,7 +193,7 @@ macro_rules! meta_num_slots_default {
191193
#[macro_export]
192194
macro_rules! meta_num_slots_global {
193195
($coop_pref:expr) => {
194-
if ::alloc::alloc::Global::CO_ALLOCATES_WITH_META && ($coop_pref) { 1 } else { 0 }
196+
if ::alloc::alloc::Global::CO_ALLOC_META_NUM_SLOTS && ($coop_pref) { 1 } else { 0 }
195197
};
196198
}
197199

@@ -205,6 +207,6 @@ macro_rules! meta_num_slots_global {
205207
#[macro_export]
206208
macro_rules! meta_num_slots_default_global {
207209
() => {
208-
if ::alloc::alloc::Global::CO_ALLOCATES_WITH_META && (DEFAULT_COOP_PREF!()) { 1 } else { 0 }
210+
if ::alloc::alloc::Global::CO_ALLOC_META_NUM_SLOTS && (DEFAULT_COOP_PREF!()) { 1 } else { 0 }
209211
};
210212
}

library/alloc/src/raw_vec.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")]
22

3+
use crate::meta_num_slots_default;
34
use core::alloc::{self, LayoutError, PtrAndMeta};
45
use core::cmp;
56
use core::intrinsics;
@@ -120,6 +121,10 @@ impl<T, A: Allocator, const COOP_PREF: bool> RawVec<T, A, COOP_PREF>
120121
where
121122
[(); alloc::co_alloc_metadata_num_slots_with_preference::<A>(COOP_PREF)]:,
122123
{
124+
const fn new_plain_metas() -> [A::CoAllocMeta; {meta_num_slots_default!(A)}] {
125+
loop {}
126+
}
127+
123128
// Tiny Vecs are dumb. Skip to:
124129
// - 8 if the element size is 1, because any heap allocators is likely
125130
// to round up a request of less than 8 bytes to at least 8 bytes.

library/core/src/alloc/mod.rs

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,75 @@ impl fmt::Display for AllocError {
4848
}
4949
}
5050

51+
/// `CoAllocPref` values indicate a type's preference for coallocation (in either user space, or
52+
/// `std` space). Used as a `const` generic parameter type (usually called `CO_ALLOC_PREF`).
53+
///
54+
/// The actual value may be overriden by the allocator. See also `CoAllocMetaNumSlotsPref` and
55+
/// `co_alloc_pref` macro .
56+
///
57+
/// This type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
58+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence:
59+
/// - DO NOT construct instances, but use `co_alloc_pref` macro together with constants
60+
/// `CO_ALLOC_PREF_YES` and `CO_ALLOC_PREF_NO`;
61+
/// - DO NOT hard code any values; and
62+
/// - DO NOT mix this/cast this with/to `usize` (nor any other integers).
63+
///
64+
/// @FIXME CO_ALLOC_PREF_DEFAULT - as a separate constant, or a "keyword" recognized by
65+
/// `co_alloc_pref` macro?
66+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
67+
pub type CoAllocPref = usize;
68+
69+
/// `CoAllocMetaNumSlotsPref` values indicate a type prefers to coallocate by carrying metadata, or
70+
/// not. (In either user space, or `std` space). Used as an argument to macro call of
71+
/// `co_alloc_pref`, which generates a `CoAllocPref` value.
72+
///
73+
/// Currently this indicates only the (preferred) number of `CoAllocMetaBase` slots being used
74+
/// (either 1 = coallocation, or 0 = no coallocation). However, in the future this type may have
75+
/// other properties (serving as extra hints to the allocator).
76+
///
77+
/// The actual value may be overriden by the allocator. For example, if the allocator doesn't
78+
/// support coallocation, then whether this value prefers to coallocate or not makes no difference.
79+
///
80+
/// This type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
81+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence:
82+
/// - DO NOT mix this/cast this with/to `isize` (nor any other integers); and
83+
/// - DO NOT hard code any values, but use `CO_ALLOC_PREF_YES` and `CO_ALLOC_PREF_NO`.
84+
///
85+
/// Currently this type is intentionally not `usize`. Why? This helps to prevent mistakes when one
86+
/// would use `CO_ALLOC_PREF_YES` or `CO_ALLOC_PREF_NO` in place of `CoAllocPref` vales.
87+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
88+
pub type CoAllocMetaNumSlotsPref = isize;
89+
90+
/// "Yes" as a type's preference for coallocation (in either user space, or `std` space).
91+
///
92+
/// It may be overriden by the allocator. For example, if the allocator doesn't support
93+
/// coallocation, then this value makes no difference.
94+
///
95+
/// This constant and its type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
96+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence DO NOT hard
97+
/// code/replace/mix this any other values/parameters.
98+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
99+
pub const CO_ALLOC_PREF_YES: CoAllocMetaNumSlotsPref = 1;
100+
101+
/// "No" as a type's preference for coallocation (in either user space, or `std` space).
102+
///
103+
/// Any allocator is required to respect this. Even if the allocator does support coallocation, it
104+
/// will not coallocate types that use this value.
105+
///
106+
/// This constant and its type WILL CHANGE (once ``#![feature(generic_const_exprs)]` and
107+
/// `#![feature(adt_const_params)]` are stable) to a dedicated struct/enum. Hence DO NOT hard
108+
/// code/replace/mix this any other values/parameters.
109+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
110+
pub const CO_ALLOC_PREF_NO: CoAllocMetaNumSlotsPref = 0;
111+
112+
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
113+
#[macro_export]
114+
macro_rules! co_alloc_pref {
115+
($coop_pref:expr) => {
116+
if ::alloc::alloc::Global::CO_ALLOC_META_NUM_SLOTS && ($coop_pref) { 1 } else { 0 }
117+
};
118+
}
119+
51120
/// (Non-Null) Pointer and coallocation metadata.
52121
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
53122
#[derive(Clone, Copy, Debug)]
@@ -79,14 +148,13 @@ macro_rules! SHORT_TERM_VEC_PREFERS_COOP {
79148
pub type SliceAndMetaResult<M> = Result<SliceAndMeta<M>, AllocError>;
80149

81150
// @FIXME REMOVE
82-
/// Return 0 or 1, indicating whether to use coallocation metadata or not.
83-
/// Param `coop_preferred` - if false, then this returns `0`, regardless of
84-
/// whether allocator `A` is cooperative.
151+
/// Return 0 or 1, indicating whether to use coallocation metadata or not. Param `coop_preferred` -
152+
/// if false, then this returns `0`, regardless of whether allocator `A` is cooperative.
85153
#[unstable(feature = "global_co_alloc", issue = "none")]
86154
pub const fn co_alloc_metadata_num_slots_with_preference<A: Allocator>(
87155
coop_preferred: bool,
88156
) -> usize {
89-
if A::CO_ALLOCATES_WITH_META && coop_preferred { 1 } else { 0 }
157+
if coop_preferred { A::CO_ALLOC_META_NUM_SLOTS } else { 0 }
90158
}
91159

92160
/// An implementation of `Allocator` can allocate, grow, shrink, and deallocate arbitrary blocks of
@@ -148,15 +216,18 @@ pub const fn co_alloc_metadata_num_slots_with_preference<A: Allocator>(
148216
#[unstable(feature = "allocator_api", issue = "32838")]
149217
#[const_trait]
150218
pub unsafe trait Allocator {
151-
//const fn is_co_allocator() -> bool {false}
152-
// Can't have: const type Xyz;
153-
/// If this is any type with non-zero size, then the actual `Allocator` implementation supports cooperative functions (`co_*`) as first class citizens.
154-
//type IsCoAllocator = ();
155-
// It applies to the global (default) allocator only. And/or System allocator?! @FIXME
156-
const CO_ALLOCATES_WITH_META: bool = false;
219+
//const fn is_co_allocator() -> bool {false} Can't have: const type Xyz;
220+
/// If this is any type with non-zero size, then the actual `Allocator` implementation supports
221+
/// cooperative functions (`co_*`) as first class citizens.
222+
//type IsCoAllocator = (); It applies to the global (default) allocator only. And/or System
223+
// allocator?! @FIXME
224+
/// NOT for public use. MAY CHANGE.
225+
///
226+
/// Either 0 or 1.
227+
const CO_ALLOC_META_NUM_SLOTS: usize = 0;
157228

158229
/// NOT for public use. The default value MAY be REMOVED or CHANGED.
159-
///
230+
///
160231
/// @FIXME Validate (preferrable at compile time, otherwise as a test) that this type's
161232
/// alignment <= `usize` alignment.
162233
type CoAllocMeta: CoAllocMetaBase = CoAllocMetaPlain;
@@ -591,7 +662,13 @@ where
591662
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
592663
pub trait CoAllocMetaBase: Clone + Copy {
593664
/// NOT for public use. This MAY BE REMOVED or CHANGED.
594-
///
665+
///
666+
/// For EXPERIMENTATION only.
667+
const ZERO_METAS: [Self; 0];
668+
const ONE_METAS: [Self; 1];
669+
670+
/// NOT for public use. This MAY BE REMOVED or CHANGED.
671+
///
595672
/// For EXPERIMENTATION only.
596673
fn new_plain() -> Self;
597674
}
@@ -600,11 +677,14 @@ pub trait CoAllocMetaBase: Clone + Copy {
600677
#[derive(Clone, Copy, Debug)]
601678
pub struct CoAllocMetaPlain {}
602679

603-
static CO_ALLOC_META_PLAIN: CoAllocMetaPlain = CoAllocMetaPlain {};
680+
const CO_ALLOC_META_PLAIN: CoAllocMetaPlain = CoAllocMetaPlain {};
604681

605682
#[unstable(feature = "global_co_alloc_meta", issue = "none")]
606683
impl CoAllocMetaBase for CoAllocMetaPlain {
684+
const ZERO_METAS: [Self; 0] = [];
685+
const ONE_METAS: [Self; 1] = [CO_ALLOC_META_PLAIN];
686+
607687
fn new_plain() -> Self {
608688
CO_ALLOC_META_PLAIN
609689
}
610-
}
690+
}

0 commit comments

Comments
 (0)