Skip to main content

NtAlloc

Struct NtAlloc 

Source
pub struct NtAlloc<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32 = DEFAULT_MEMORY_TAG, const TAGGED_DEALLOC: bool = true, const REALIGN: bool = true>;
Expand description

A stateless, #![no_std]-friendly Windows kernel pool allocator.

NtAlloc is a zero-sized type: all of its behavior is selected entirely at compile time via its const generic parameters, and every operation is exposed as an associated function, so no instance ever needs to be constructed to use them directly. An instance is still needed to satisfy the GlobalAlloc trait bound (and, with the allocator-api feature, the Allocator one), and can always be created with Default::default() at zero runtime cost.

§Type Parameters

Prefer the PagedAlloc/NonPagedAlloc aliases over naming NtAlloc directly, unless the configuration needs more flags than the pool:

use ntalloc::{NtAlloc, POOL_FLAG_NON_PAGED, POOL_FLAG_UNINITIALIZED};

// Non-paged pool that skips the zeroing ExAllocatePool2 otherwise does.
type ScratchAlloc = NtAlloc<{ POOL_FLAG_NON_PAGED | POOL_FLAG_UNINITIALIZED }>;

assert!(!ScratchAlloc::POOL_ZEROES);

Call associated functions through an alias that names the whole type, such as type Alloc = NonPagedAlloc; followed by Alloc::allocate(64). Writing NonPagedAlloc::allocate(64) does not compile (E0284): Rust fills in the aliases’ default parameters only where a type is expected.

§Turning realignment off

Realignment is on by default. A driver that never needs more than the pool’s own alignment can turn it off by setting REALIGN to false: NtAlloc::allocate_aligned, and with it the GlobalAlloc and Allocator implementations, then pass every request to the pool by size and ignore the alignment it asks for. Nothing is over-allocated or stored next to a block, and a block is aligned only as the pool aligns it: to MIN_ALIGNMENT below a page, and to a page from one page up.

Only do so if nothing allocated through such a configuration needs more, including types from other crates, which a #[global_allocator] serves too. Anything #[repr(align(32))] or larger needs more, as do 256- and 512-bit SIMD vectors and cache-padded wrappers such as crossbeam’s CachePadded. A misaligned Box or reference is undefined behaviour, and an aligned SIMD load from one faults, which in a driver is a bug check. Debug builds usually stop at the first misaligned access, with “misaligned pointer dereference”; release builds do not.

use core::alloc::{GlobalAlloc, Layout};
use ntalloc::{DEFAULT_MEMORY_TAG, MIN_ALIGNMENT, NonPagedAlloc};

type NoRealignAlloc = NonPagedAlloc<DEFAULT_MEMORY_TAG, true, false>;

let alloc = NoRealignAlloc::default();

// Asks for 64-byte alignment, but gets only what the pool gives a small block.
let layout = Layout::from_size_align(64, 64).unwrap();
// SAFETY: the layout has a non-zero size.
let ptr = unsafe { alloc.alloc(layout) };
assert!(!ptr.is_null());
assert_eq!(ptr as usize % MIN_ALIGNMENT, 0);

// SAFETY: from `alloc` with this layout, freed once.
unsafe { alloc.dealloc(ptr, layout) };

§Unsupported configurations

These configurations break ExAllocatePool2’s documented rules, fail every allocation, are listed by Microsoft as bug checks, or fail in a way Rust cannot handle, so a type that uses one fails to build as soon as anything allocates with it. The error comes from cargo build; cargo check does not evaluate it.

  • POOL_FLAG_RAISE_ON_FAILURE (0x20) makes ExAllocatePool2 raise an SEH exception on failure instead of returning null. Rust cannot catch SEH: left unhandled the exception bugchecks the system, and handled further up it unwinds through Rust frames, which is undefined behaviour.
  • A zero MEMORY_TAG, which ExAllocatePool2 rejects as invalid.
  • A MEMORY_TAG that is not one to four printable ASCII characters (0x20 to 0x7E) followed only by zero padding, as ExAllocatePool2’s documentation requires: one with a control byte, a byte above 0x7E, or a zero byte before its last character.
  • A MEMORY_TAG with no ASCII letter or digit, such as four spaces, which Microsoft lists as bug check BAD_POOL_CALLER (0x9D).
  • "BIG ", a tag the kernel reserves, which Microsoft lists as bug check BAD_POOL_CALLER (0x9C).

Without POOL_FLAG_RAISE_ON_FAILURE, failure is reported as null. Fallible APIs such as Box::try_new_in return it as an error, and infallible ones such as Box::new pass it to handle_alloc_error, which in a #![no_std] build panics by default: the fail-fast behaviour the flag would otherwise give.

The flags are not validated beyond that: any other combination the pool considers invalid fails at run time, like any other allocation failure.

ⓘ
use ntalloc::{NtAlloc, POOL_FLAG_NON_PAGED};

// 0x20 is POOL_FLAG_RAISE_ON_FAILURE, which this crate does not export.
type Raising = NtAlloc<{ POOL_FLAG_NON_PAGED | 0x20 }>;

let _ = Raising::allocate(64);
ⓘ
use ntalloc::{NtAlloc, POOL_FLAG_NON_PAGED};

type Untagged = NtAlloc<POOL_FLAG_NON_PAGED, 0>;

let _ = Untagged::allocate(64);
ⓘ
use ntalloc::{NtAlloc, POOL_FLAG_NON_PAGED};

// A zero byte before the last character.
type Gapped = NtAlloc<POOL_FLAG_NON_PAGED, { u32::from_ne_bytes(*b"ab\0c") }>;

let _ = Gapped::allocate(64);
ⓘ
use ntalloc::{NtAlloc, POOL_FLAG_NON_PAGED};

type Blank = NtAlloc<POOL_FLAG_NON_PAGED, { u32::from_ne_bytes(*b"    ") }>;

let _ = Blank::allocate(64);
ⓘ
use ntalloc::{NtAlloc, POOL_FLAG_NON_PAGED};

type Big = NtAlloc<POOL_FLAG_NON_PAGED, { u32::from_ne_bytes(*b"BIG ") }>;

let _ = Big::allocate(64);

Implementations§

Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source

pub const POOL_ZEROES: bool

Whether allocations from this configuration arrive zero-initialized.

ExAllocatePool2 zeroes every block it returns unless POOL_FLAG_UNINITIALIZED is among ALLOC_POOL_FLAGS, so this is a property of the type, resolved at compile time. It is true for PagedAlloc and NonPagedAlloc.

GlobalAlloc::alloc_zeroed, and with the allocator-api feature Allocator::allocate_zeroed, consult it to skip the redundant second pass their default implementations would otherwise make over memory the pool has already zeroed.

Source

pub fn kernel_alignment(size: usize) -> usize

Returns the alignment guarantee ExAllocatePool2 provides for an allocation of size bytes.

Per the ExAllocatePool2 documentation, allocations of at least one page are page-aligned; smaller allocations are only guaranteed MIN_ALIGNMENT.

§Parameters
  • size: the requested allocation size, in bytes.
§Returns

PAGE_SIZE if size is at least one page, otherwise MIN_ALIGNMENT.

§Examples
use ntalloc::{PagedAlloc, MIN_ALIGNMENT};
use windows_sys::Wdk::System::SystemServices::PAGE_SIZE;

type Alloc = PagedAlloc;

assert_eq!(Alloc::kernel_alignment(16), MIN_ALIGNMENT);
assert_eq!(Alloc::kernel_alignment(PAGE_SIZE as usize), PAGE_SIZE as usize);
Source

pub fn kernel_allocate(size: usize) -> *mut u8

Allocates size bytes directly from the kernel pool via ExAllocatePool2, bypassing the process-heap backend that NtAlloc::allocate uses in tests and under the usermode-backend feature. It always reaches the pool, so outside a kernel it can only be called with a size of 0.

§Parameters
  • size: the number of bytes to allocate. A zero-size request never reaches the pool: ExAllocatePool2 documents NumberOfBytes as “a non-zero number of bytes”, and lists only memory exhaustion and a bad tag or flags as reasons it returns null — so it defines no behaviour at all for 0. This returns null instead.
§Returns

A pointer to the allocated memory, or a null pointer if size is 0 or the allocation fails.

§Examples
use ntalloc::NonPagedAlloc;

type Alloc = NonPagedAlloc;

let ptr = Alloc::kernel_allocate(64);
assert!(!ptr.is_null());
Source

pub fn allocate(size: usize) -> *mut u8

Allocates size bytes, returning a null pointer for a zero-size request.

With the usermode-backend feature, and in this crate’s own tests, allocation is redirected to the process heap so that the allocator’s logic can run without a kernel; otherwise this calls NtAlloc::kernel_allocate.

The zero-size check lives in each backend rather than here, so the shipped path performs it once instead of twice.

§Parameters
  • size: the number of bytes to allocate.
§Returns

A pointer to the allocated memory, or a null pointer if size is 0 or the allocation fails.

§Examples
use ntalloc::NonPagedAlloc;

type Alloc = NonPagedAlloc;

let ptr = Alloc::allocate(64);
assert!(!ptr.is_null());
// SAFETY: `ptr` came from `Alloc::allocate` and needed no realignment.
unsafe { Alloc::deallocate(ptr) };
Source

pub fn allocate_aligned(layout: Layout) -> *mut u8

Allocates memory for layout, handling alignment requirements stronger than what the kernel pool allocator natively provides.

If layout.align() is no stronger than NtAlloc::kernel_alignment for the requested size, this simply forwards to NtAlloc::allocate. Otherwise it over-allocates by layout.align() extra bytes, rounds the result up to layout.align(), and stashes the original pointer just before the returned one (see the crate-level documentation for details). With REALIGN set to false it forwards every request to NtAlloc::allocate instead: see Turning realignment off.

§Parameters
  • layout: the size and alignment to allocate for.
§Returns

A pointer to layout.size() bytes aligned to layout.align() (only to the pool’s own alignment when REALIGN is false), or a null pointer on allocation failure.

A zero-size layout always returns a null pointer, and never reaches the pool. GlobalAlloc calls a zero-size request undefined behaviour but invites implementations to “guarantee a sentinel address or a null pointer in response to a zero-size allocation request” — this is that guarantee. Callers needing a usable pointer for an empty allocation want the Allocator impl (the allocator-api feature), which returns a dangling one as that trait requires.

§Note

A pointer returned from this function when realignment was required cannot be freed with the plain NtAlloc::deallocate — that function has no way to recover the original pointer. Free it with NtAlloc::deallocate_aligned, passing the same layout, or through this type’s GlobalAlloc/Allocator implementations, which do the same thing. (For a pointer that did not need realignment, NtAlloc::deallocate is fine either way — but since only layout distinguishes the two cases, always pairing with NtAlloc::deallocate_aligned is the rule that cannot go wrong.)

§Examples
use core::alloc::Layout;
use ntalloc::NonPagedAlloc;

type Alloc = NonPagedAlloc;

let layout = Layout::from_size_align(16, 64).unwrap();
let ptr = Alloc::allocate_aligned(layout);
assert!(!ptr.is_null());
assert_eq!(ptr as usize % layout.align(), 0);

// SAFETY: `ptr` came from `allocate_aligned` with this exact layout.
unsafe { Alloc::deallocate_aligned(ptr, layout) };
Source

pub unsafe fn deallocate(ptr: *mut u8)

Frees a pointer previously returned by NtAlloc::allocate. Normally that is a pool block, which NtAlloc::kernel_allocate returns too, freed with the routine TAGGED_DEALLOC selects. Under the usermode-backend feature both functions use the process heap instead.

This does not account for the pointer-stashing done by NtAlloc::allocate_aligned for over-aligned requests — see that function’s documentation for when it is safe to call this directly.

§Safety

The caller must guarantee all of the following:

  • ptr is non-null. Unlike NtAlloc::deallocate_aligned, this function does not check, and ExFreePool/ExFreePoolWithTag bugchecks on a null pointer rather than ignoring it the way C’s free would.
  • ptr came from the same NtAlloc configuration: the same pool flags, the same MEMORY_TAG, and the same TAGGED_DEALLOC. Freeing with a mismatched tag corrupts the pool.
  • ptr is the address the pool returned, not one that NtAlloc::allocate_aligned adjusted for over-alignment. Those go to NtAlloc::deallocate_aligned instead.
  • ptr has not already been freed, and is not used afterwards.
§Examples
use ntalloc::NonPagedAlloc;

type Alloc = NonPagedAlloc;

let ptr = Alloc::allocate(64);
assert!(!ptr.is_null());
// SAFETY: `ptr` came from `Alloc::allocate` and needed no realignment.
unsafe { Alloc::deallocate(ptr) };
Source

pub unsafe fn deallocate_aligned(ptr: *mut u8, layout: Layout)

Frees a pointer returned by NtAlloc::allocate_aligned for layout, recovering and freeing the original (pre-realignment) pointer when layout’s alignment required over-allocation.

This is the counterpart to NtAlloc::allocate_aligned: a pointer from that function must be freed through this one, because for an over-aligned request the address handed out is not the address the pool returned, and only this function knows how to recover it.

Passing a null ptr is a no-op.

§Safety

The caller must guarantee all of the following:

  • ptr was returned by NtAlloc::allocate_aligned on this same NtAlloc instantiation — the same pool flags, the same MEMORY_TAG, the same TAGGED_DEALLOC and the same REALIGN — or is null.
  • layout is the exact Layout that was passed to that call. layout alone decides whether the original pointer is read back from the slot before ptr or ptr is freed directly, so a mismatched layout will either hand ExFreePool an interior pointer or read POINTER_SIZE bytes of unrelated memory and free whatever they happen to contain.
  • ptr has not already been freed, and is not used afterwards.

None of these can be checked at runtime: an interior pointer and a valid one are indistinguishable, and the pool allocator has no way to report that a tag or a size did not match.

Trait Implementations§

Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Allocator for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Available on crate feature allocator-api only.
Source§

fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Allocates memory for layout via NtAlloc::allocate_aligned, returning it as a NonNull<[u8]> slice.

§Returns
  • Ok(_) — a NonNull<[u8]> slice of exactly layout.size() bytes (never more, even though the real underlying allocation may be larger than that once realignment padding is accounted for).
  • Ok(_) — for a zero-size layout, a dangling pointer aligned to layout.align() with a length of 0. Allocator requires zero-sized allocations to succeed, unlike GlobalAlloc, and the pool is never involved. Passing it back to Allocator::deallocate is correct and does nothing.
  • Err(AllocError) — only if the underlying pool allocation fails.
Source§

fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Allocates zero-initialized memory for layout.

Skips the second zeroing pass the default implementation would make whenever NtAlloc::POOL_ZEROES holds, for the reasons given on GlobalAlloc::alloc_zeroed. A zero-sized layout yields the same dangling, length-0 slice Allocator::allocate returns, which is trivially zeroed.

Source§

unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout)

Frees a pointer previously returned by Allocator::allocate (or grow/shrink) on this same allocator.

§Safety

ptr must denote memory currently allocated via this allocator, and layout must be the same layout that was used to allocate it, per the Allocator::deallocate contract.

1.100.0 (const: unstable) · Source§

unsafe fn grow( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to extend the memory block. Read more
1.100.0 (const: unstable) · Source§

unsafe fn grow_zeroed( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Behaves like grow, but also ensures that the new contents are set to zero before being returned. Read more
1.100.0 (const: unstable) · Source§

unsafe fn shrink( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to shrink the memory block. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> AllocatorClone for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Available on crate feature allocator-api-markers only.
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Clone for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Copy for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Debug for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Default for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Eq for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> GlobalAlloc for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

unsafe fn alloc(&self, layout: Layout) -> *mut u8

Allocates memory for layout via NtAlloc::allocate_aligned.

§Safety

As GlobalAlloc::alloc requires: layout must have non-zero size, and the caller must pass the exact same layout to GlobalAlloc::dealloc (or realloc) when freeing the returned pointer.

Should a zero-size layout arrive anyway, this returns null rather than reaching ExAllocatePool2, which documents no behaviour for a zero-size request. See NtAlloc::allocate_aligned.

Source§

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout)

Frees a pointer previously returned by GlobalAlloc::alloc (or realloc) on this same allocator, correctly recovering any pointer adjustment NtAlloc::allocate_aligned made for over-aligned requests.

§Safety

ptr must have been returned by a prior call to GlobalAlloc::alloc (or realloc) on this same NtAlloc instantiation, and layout must be the exact layout used for that allocation.

Source§

unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8

Allocates zero-initialized memory for layout.

The default implementation of this method allocates and then writes zeroes over the whole block. ExAllocatePool2 has already done that, so when NtAlloc::POOL_ZEROES holds this simply returns the allocation and the second pass is skipped — the condition is a const, so only one branch survives compilation.

For a realigned request the returned region still arrives zeroed: it lies inside the larger block the pool zeroed, and the pointer NtAlloc::allocate_aligned stashes goes in the bytes before it.

§Safety

As GlobalAlloc::alloc: layout must have non-zero size, and the same layout must come back on the free path.

1.28.0 · Source§

unsafe fn realloc( &self, ptr: *mut u8, layout: Layout, new_size: usize, ) -> *mut u8

Shrinks or grows a block of memory to the given new_size in bytes. The block is described by the given ptr pointer and layout. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Hash for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Ord for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> PartialEq for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> PartialOrd for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> StaticAllocator for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Available on crate feature allocator-api-markers only.
Source§

impl<const ALLOC_POOL_FLAGS: POOL_FLAGS, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> StructuralPartialEq for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Auto Trait Implementations§

§

impl<const ALLOC_POOL_FLAGS: u64, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Freeze for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

§

impl<const ALLOC_POOL_FLAGS: u64, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> RefUnwindSafe for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

§

impl<const ALLOC_POOL_FLAGS: u64, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Send for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

§

impl<const ALLOC_POOL_FLAGS: u64, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Sync for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

§

impl<const ALLOC_POOL_FLAGS: u64, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> Unpin for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

§

impl<const ALLOC_POOL_FLAGS: u64, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> UnsafeUnpin for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

§

impl<const ALLOC_POOL_FLAGS: u64, const MEMORY_TAG: u32, const TAGGED_DEALLOC: bool, const REALIGN: bool> UnwindSafe for NtAlloc<ALLOC_POOL_FLAGS, MEMORY_TAG, TAGGED_DEALLOC, REALIGN>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.