pub struct SynchronizedAllocator<'device> { /* private fields */ }Expand description
One allocator with synchronized direct operations and concurrent pool scopes.
Placement uses one mutex per owner. Direct map/unmap/bind operations acquire a live allocation lease, then execute under that backing’s stable mutex without the placement mutex. Other backings can map/bind, allocate and free concurrently, including inside the same pool. Regions sharing one backing serialize native map/bind work and retain exact explicit/persistent counts. The first such operation fallibly reserves callback-owned backing metadata.
Borrowed results, relocation and global services use exclusive access and
wait for outstanding native leases. try_with_allocator reports busy during
those leases. Borrowed pool/type/block scopes add independent placement
owners for their documented domains. There is no process-global lock or
new Send/Sync assertion on ordinary Allocator. Performance is unmeasured.
Callbacks must never reenter this owner or create cross-owner lock cycles.
Vulkan completion and mapped-byte synchronization remain caller obligations.
Drop frees CPU metadata only; explicitly close native storage before Drop.
A scoped operation cannot return its allocator borrow:
let escaped = unsafe { shared.with_allocator(|allocator| allocator) };An existing ordinary allocator’s device borrow may still be shortened:
fn shorten<'device: 'scope, 'scope>(owner: vk::Allocator<'device>) -> vk::Allocator<'scope> {
owner
}The ordinary allocator remains non-Send:
fn require_send<T: Send>() {}
require_send::<vk::Allocator<'static>>();// SAFETY: retained chains/callbacks and mapped storage satisfy new's
// any-thread contract through final host cleanup.
let shared = unsafe { vk::SynchronizedAllocator::new(allocator) };
std::thread::scope(|scope| {
scope.spawn(|| {
// SAFETY: no replacement/thread-affine state is installed; no
// native work is live and ordinary close preconditions hold.
unsafe { shared.with_allocator(|allocator| allocator.close()) }??;
Ok::<_, vk::AllocError>(())
}).join().unwrap()
})?;Implementations§
Source§impl<'device> SynchronizedAllocator<'device>
impl<'device> SynchronizedAllocator<'device>
Sourcepub fn live_count(&self) -> Result<usize, AllocError>
pub fn live_count(&self) -> Result<usize, AllocError>
Number of live allocation registrations under this allocator’s lock.
§Errors
Returns SynchronizationPoisoned after a closure panic.
Sourcepub fn is_closed(&self) -> Result<bool, AllocError>
pub fn is_closed(&self) -> Result<bool, AllocError>
Observe explicit close state under this allocator’s lock.
§Errors
Returns SynchronizationPoisoned after a closure panic.
Sourcepub fn max_allocation_size(&self) -> Result<Option<u64>, AllocError>
pub fn max_allocation_size(&self) -> Result<Option<u64>, AllocError>
Optional caller-configured size limit under this allocator’s lock.
§Errors
Returns SynchronizationPoisoned after a closure panic.
Sourcepub fn close(&self) -> Result<(), AllocError>
pub fn close(&self) -> Result<(), AllocError>
Close the allocator under its lock; later access reports Closed.
Concurrent operations complete or fail before this runs.
§Errors
Same live-resource errors as Allocator::close, plus SynchronizationPoisoned.
Sourcepub fn allocator_info(&self) -> Result<AllocatorInfo, AllocError>
pub fn allocator_info(&self) -> Result<AllocatorInfo, AllocError>
Captured native identities under this allocator’s lock.
§Errors
Same errors as Allocator::allocator_info, plus SynchronizationPoisoned.
Sourcepub fn memory_type_properties(
&self,
index: u32,
) -> Result<MemoryPropertyFlags, AllocError>
pub fn memory_type_properties( &self, index: u32, ) -> Result<MemoryPropertyFlags, AllocError>
Queried properties of one native memory type under this allocator’s lock.
§Errors
Same errors as Allocator::memory_type_properties, plus SynchronizationPoisoned.
Sourcepub fn find_memory_type(
&self,
bits: u32,
options: &AllocationCreateInfo<'_>,
) -> Result<u32, AllocError>
pub fn find_memory_type( &self, bits: u32, options: &AllocationCreateInfo<'_>, ) -> Result<u32, AllocError>
Score memory types for one allocation request under this allocator’s lock.
§Errors
Same errors as Allocator::find_memory_type, plus SynchronizationPoisoned.
Sourcepub unsafe fn find_memory_type_for_buffer_info(
&self,
info: &BufferCreateInfo<'_>,
options: &AllocationCreateInfo<'_>,
) -> Result<u32, AllocError>
pub unsafe fn find_memory_type_for_buffer_info( &self, info: &BufferCreateInfo<'_>, options: &AllocationCreateInfo<'_>, ) -> Result<u32, AllocError>
Sourcepub unsafe fn find_memory_type_for_image_info(
&self,
info: &ImageCreateInfo<'_>,
options: &AllocationCreateInfo<'_>,
) -> Result<u32, AllocError>
pub unsafe fn find_memory_type_for_image_info( &self, info: &ImageCreateInfo<'_>, options: &AllocationCreateInfo<'_>, ) -> Result<u32, AllocError>
Sourcepub unsafe fn allocate(
&self,
request: &AllocRequest,
) -> Result<Allocation, AllocError>
pub unsafe fn allocate( &self, request: &AllocRequest, ) -> Result<Allocation, AllocError>
Sourcepub unsafe fn allocate_with_options(
&self,
requirements: &MemoryRequirements,
options: &AllocationCreateInfo<'_>,
) -> Result<Allocation, AllocError>
pub unsafe fn allocate_with_options( &self, requirements: &MemoryRequirements, options: &AllocationCreateInfo<'_>, ) -> Result<Allocation, AllocError>
Sourcepub unsafe fn allocate_dedicated(
&self,
requirements: &MemoryRequirements,
options: &AllocationCreateInfo<'_>,
chain: Option<AllocationChain<'_>>,
) -> Result<Allocation, AllocError>
pub unsafe fn allocate_dedicated( &self, requirements: &MemoryRequirements, options: &AllocationCreateInfo<'_>, chain: Option<AllocationChain<'_>>, ) -> Result<Allocation, AllocError>
Sourcepub unsafe fn allocate_many(
&self,
requirements: &MemoryRequirements,
options: &AllocationCreateInfo<'_>,
count: usize,
) -> Result<Vec<Allocation>, AllocError>
pub unsafe fn allocate_many( &self, requirements: &MemoryRequirements, options: &AllocationCreateInfo<'_>, count: usize, ) -> Result<Vec<Allocation>, AllocError>
Sourcepub unsafe fn free(&self, allocation: &mut Allocation) -> Result<(), AllocError>
pub unsafe fn free(&self, allocation: &mut Allocation) -> Result<(), AllocError>
Sourcepub unsafe fn free_many(
&self,
allocations: &mut [Allocation],
) -> Result<(), AllocError>
pub unsafe fn free_many( &self, allocations: &mut [Allocation], ) -> Result<(), AllocError>
Sourcepub fn allocation_info(
&self,
allocation: &Allocation,
) -> Result<AllocationInfo, AllocError>
pub fn allocation_info( &self, allocation: &Allocation, ) -> Result<AllocationInfo, AllocError>
Checked allocation snapshot under this allocator’s lock.
§Errors
Same errors as Allocator::allocation_info, plus SynchronizationPoisoned.
Sourcepub fn set_allocation_pinned(
&self,
allocation: &Allocation,
pinned: bool,
) -> Result<(), AllocError>
pub fn set_allocation_pinned( &self, allocation: &Allocation, pinned: bool, ) -> Result<(), AllocError>
Run Allocator::set_allocation_pinned under this allocator’s lock.
§Errors
Same errors as Allocator::set_allocation_pinned, plus SynchronizationPoisoned.
Sourcepub fn set_allocation_name(
&self,
allocation: &Allocation,
name: Option<&str>,
) -> Result<(), AllocError>
pub fn set_allocation_name( &self, allocation: &Allocation, name: Option<&str>, ) -> Result<(), AllocError>
Run Allocator::set_allocation_name under this allocator’s lock.
§Errors
Same errors as Allocator::set_allocation_name, plus SynchronizationPoisoned.
Sourcepub fn set_allocation_user_data(
&self,
allocation: &Allocation,
data: usize,
) -> Result<(), AllocError>
pub fn set_allocation_user_data( &self, allocation: &Allocation, data: usize, ) -> Result<(), AllocError>
Run Allocator::set_allocation_user_data under this allocator’s lock.
§Errors
Same errors as Allocator::set_allocation_user_data, plus SynchronizationPoisoned.
Sourcepub unsafe fn create_buffer(
&self,
info: &BufferCreateInfo<'_>,
required: MemoryPropertyFlags,
preferred: MemoryPropertyFlags,
) -> Result<(Buffer, Allocation), AllocError>
pub unsafe fn create_buffer( &self, info: &BufferCreateInfo<'_>, required: MemoryPropertyFlags, preferred: MemoryPropertyFlags, ) -> Result<(Buffer, Allocation), AllocError>
Sourcepub unsafe fn create_buffer_with_options(
&self,
info: &BufferCreateInfo<'_>,
options: &AllocationCreateInfo<'_>,
) -> Result<(Buffer, Allocation), AllocError>
pub unsafe fn create_buffer_with_options( &self, info: &BufferCreateInfo<'_>, options: &AllocationCreateInfo<'_>, ) -> Result<(Buffer, Allocation), AllocError>
Sourcepub unsafe fn create_dedicated_buffer(
&self,
info: &BufferCreateInfo<'_>,
options: &AllocationCreateInfo<'_>,
chain: Option<AllocationChain<'_>>,
) -> Result<(Buffer, Allocation), AllocError>
pub unsafe fn create_dedicated_buffer( &self, info: &BufferCreateInfo<'_>, options: &AllocationCreateInfo<'_>, chain: Option<AllocationChain<'_>>, ) -> Result<(Buffer, Allocation), AllocError>
Sourcepub unsafe fn destroy_buffer(
&self,
buffer: Buffer,
allocation: &mut Allocation,
) -> Result<(), AllocError>
pub unsafe fn destroy_buffer( &self, buffer: Buffer, allocation: &mut Allocation, ) -> Result<(), AllocError>
Sourcepub unsafe fn create_image(
&self,
info: &ImageCreateInfo<'_>,
required: MemoryPropertyFlags,
preferred: MemoryPropertyFlags,
) -> Result<(Image, Allocation), AllocError>
pub unsafe fn create_image( &self, info: &ImageCreateInfo<'_>, required: MemoryPropertyFlags, preferred: MemoryPropertyFlags, ) -> Result<(Image, Allocation), AllocError>
Sourcepub unsafe fn create_image_with_options(
&self,
info: &ImageCreateInfo<'_>,
options: &AllocationCreateInfo<'_>,
) -> Result<(Image, Allocation), AllocError>
pub unsafe fn create_image_with_options( &self, info: &ImageCreateInfo<'_>, options: &AllocationCreateInfo<'_>, ) -> Result<(Image, Allocation), AllocError>
Sourcepub unsafe fn create_dedicated_image(
&self,
info: &ImageCreateInfo<'_>,
options: &AllocationCreateInfo<'_>,
chain: Option<AllocationChain<'_>>,
) -> Result<(Image, Allocation), AllocError>
pub unsafe fn create_dedicated_image( &self, info: &ImageCreateInfo<'_>, options: &AllocationCreateInfo<'_>, chain: Option<AllocationChain<'_>>, ) -> Result<(Image, Allocation), AllocError>
Sourcepub unsafe fn destroy_image(
&self,
image: Image,
allocation: &mut Allocation,
) -> Result<(), AllocError>
pub unsafe fn destroy_image( &self, image: Image, allocation: &mut Allocation, ) -> Result<(), AllocError>
Sourcepub unsafe fn allocate_for_buffer(
&self,
buffer: Buffer,
options: &AllocationCreateInfo<'_>,
) -> Result<Allocation, AllocError>
pub unsafe fn allocate_for_buffer( &self, buffer: Buffer, options: &AllocationCreateInfo<'_>, ) -> Result<Allocation, AllocError>
Sourcepub unsafe fn allocate_for_image(
&self,
image: Image,
options: &AllocationCreateInfo<'_>,
) -> Result<Allocation, AllocError>
pub unsafe fn allocate_for_image( &self, image: Image, options: &AllocationCreateInfo<'_>, ) -> Result<Allocation, AllocError>
Sourcepub unsafe fn create_aliasing_buffer(
&self,
allocation: &Allocation,
local_offset: u64,
info: &BufferCreateInfo<'_>,
) -> Result<Buffer, AllocError>
pub unsafe fn create_aliasing_buffer( &self, allocation: &Allocation, local_offset: u64, info: &BufferCreateInfo<'_>, ) -> Result<Buffer, AllocError>
Sourcepub unsafe fn create_aliasing_image(
&self,
allocation: &Allocation,
local_offset: u64,
info: &ImageCreateInfo<'_>,
) -> Result<Image, AllocError>
pub unsafe fn create_aliasing_image( &self, allocation: &Allocation, local_offset: u64, info: &ImageCreateInfo<'_>, ) -> Result<Image, AllocError>
Sourcepub unsafe fn copy_to_allocation(
&self,
allocation: &Allocation,
offset: u64,
source: &[u8],
) -> Result<(), AllocError>
pub unsafe fn copy_to_allocation( &self, allocation: &Allocation, offset: u64, source: &[u8], ) -> Result<(), AllocError>
Sourcepub unsafe fn copy_from_allocation(
&self,
allocation: &Allocation,
offset: u64,
destination: &mut [u8],
) -> Result<(), AllocError>
pub unsafe fn copy_from_allocation( &self, allocation: &Allocation, offset: u64, destination: &mut [u8], ) -> Result<(), AllocError>
Sourcepub unsafe fn bind_buffer_memory(
&self,
buffer: Buffer,
allocation: &Allocation,
) -> Result<(), AllocError>
pub unsafe fn bind_buffer_memory( &self, buffer: Buffer, allocation: &Allocation, ) -> Result<(), AllocError>
Sourcepub unsafe fn bind_image_memory(
&self,
image: Image,
allocation: &Allocation,
) -> Result<(), AllocError>
pub unsafe fn bind_image_memory( &self, image: Image, allocation: &Allocation, ) -> Result<(), AllocError>
Sourcepub unsafe fn bind_buffer_memory2(
&self,
buffer: Buffer,
allocation: &Allocation,
local_offset: u64,
next: *const c_void,
) -> Result<(), AllocError>
pub unsafe fn bind_buffer_memory2( &self, buffer: Buffer, allocation: &Allocation, local_offset: u64, next: *const c_void, ) -> Result<(), AllocError>
Sourcepub unsafe fn bind_image_memory2(
&self,
image: Image,
allocation: &Allocation,
local_offset: u64,
next: *const c_void,
) -> Result<(), AllocError>
pub unsafe fn bind_image_memory2( &self, image: Image, allocation: &Allocation, local_offset: u64, next: *const c_void, ) -> Result<(), AllocError>
Sourcepub unsafe fn map(
&self,
allocation: &Allocation,
) -> Result<*mut c_void, AllocError>
pub unsafe fn map( &self, allocation: &Allocation, ) -> Result<*mut c_void, AllocError>
Run Allocator::map under a live lease and this backing’s mutex.
§Errors
Same checked/native errors as Allocator::map, plus SynchronizationPoisoned.
§Safety
May fail to reserve the stable backing metadata before native effects.
Same mapping, mapped-byte synchronization and completion contract as
Allocator::map; escaping pointers retain SynchronizedAllocator rules.
Sourcepub unsafe fn unmap(&self, allocation: &Allocation) -> Result<(), AllocError>
pub unsafe fn unmap(&self, allocation: &Allocation) -> Result<(), AllocError>
Sourcepub fn mapped_pointer(
&self,
allocation: &Allocation,
) -> Result<Option<*mut c_void>, AllocError>
pub fn mapped_pointer( &self, allocation: &Allocation, ) -> Result<Option<*mut c_void>, AllocError>
Current mapping pointer for one allocation under this allocator’s lock.
§Errors
Same errors as Allocator::mapped_pointer, plus SynchronizationPoisoned.
Sourcepub unsafe fn flush(
&self,
allocation: &Allocation,
offset: u64,
size: u64,
) -> Result<(), AllocError>
pub unsafe fn flush( &self, allocation: &Allocation, offset: u64, size: u64, ) -> Result<(), AllocError>
Sourcepub unsafe fn invalidate(
&self,
allocation: &Allocation,
offset: u64,
size: u64,
) -> Result<(), AllocError>
pub unsafe fn invalidate( &self, allocation: &Allocation, offset: u64, size: u64, ) -> Result<(), AllocError>
Sourcepub unsafe fn flush_many(
&self,
ranges: &[CacheRange<'_>],
) -> Result<(), AllocError>
pub unsafe fn flush_many( &self, ranges: &[CacheRange<'_>], ) -> Result<(), AllocError>
Sourcepub unsafe fn invalidate_many(
&self,
ranges: &[CacheRange<'_>],
) -> Result<(), AllocError>
pub unsafe fn invalidate_many( &self, ranges: &[CacheRange<'_>], ) -> Result<(), AllocError>
Sourcepub fn set_heap_limit(&self, heap: u32, limit: u64) -> Result<(), AllocError>
pub fn set_heap_limit(&self, heap: u32, limit: u64) -> Result<(), AllocError>
Run Allocator::set_heap_limit under this allocator’s lock.
§Errors
Same errors as Allocator::set_heap_limit, plus SynchronizationPoisoned.
Sourcepub fn budget_snapshot(&self) -> Result<BudgetSnapshot, AllocError>
pub fn budget_snapshot(&self) -> Result<BudgetSnapshot, AllocError>
Cached budget snapshot under this allocator’s lock.
§Errors
Returns SynchronizationPoisoned after a closure panic.
Sourcepub unsafe fn query_budget(
&self,
instance: &Instance,
physical: PhysicalDevice,
) -> Result<BudgetSnapshot, AllocError>
pub unsafe fn query_budget( &self, instance: &Instance, physical: PhysicalDevice, ) -> Result<BudgetSnapshot, AllocError>
Sourcepub fn refresh_budget(&self) -> Result<BudgetSnapshot, AllocError>
pub fn refresh_budget(&self) -> Result<BudgetSnapshot, AllocError>
Run Allocator::refresh_budget under this allocator’s lock.
§Errors
Same errors as Allocator::refresh_budget, plus SynchronizationPoisoned.
Sourcepub unsafe fn refresh_budget_with_context(
&self,
instance: &Instance,
physical: PhysicalDevice,
) -> Result<BudgetSnapshot, AllocError>
pub unsafe fn refresh_budget_with_context( &self, instance: &Instance, physical: PhysicalDevice, ) -> Result<BudgetSnapshot, AllocError>
Sourcepub fn heap_budgets(&self) -> Result<BudgetSnapshot, AllocError>
pub fn heap_budgets(&self) -> Result<BudgetSnapshot, AllocError>
Run Allocator::heap_budgets under this allocator’s lock.
§Errors
Same errors as Allocator::heap_budgets, plus SynchronizationPoisoned.
Sourcepub fn set_current_frame_index(&self, index: u32) -> Result<(), AllocError>
pub fn set_current_frame_index(&self, index: u32) -> Result<(), AllocError>
Run Allocator::set_current_frame_index under this allocator’s lock.
§Errors
Same errors as Allocator::set_current_frame_index, plus SynchronizationPoisoned.
Sourcepub fn current_frame_index(&self) -> Result<u32, AllocError>
pub fn current_frame_index(&self) -> Result<u32, AllocError>
Current frame index under this allocator’s lock.
§Errors
Returns SynchronizationPoisoned after a closure panic.
Sourcepub fn trim(&self) -> Result<TrimStats, AllocError>
pub fn trim(&self) -> Result<TrimStats, AllocError>
Run Allocator::trim under this allocator’s lock.
§Errors
Same errors as Allocator::trim, plus SynchronizationPoisoned.
Sourcepub unsafe fn trim_with_budget(
&self,
instance: &Instance,
physical: PhysicalDevice,
) -> Result<TrimStats, AllocError>
pub unsafe fn trim_with_budget( &self, instance: &Instance, physical: PhysicalDevice, ) -> Result<TrimStats, AllocError>
Sourcepub unsafe fn create_pool(
&self,
info: &PoolCreateInfo,
) -> Result<Pool, AllocError>
pub unsafe fn create_pool( &self, info: &PoolCreateInfo, ) -> Result<Pool, AllocError>
Sourcepub unsafe fn create_pool_with_chain(
&self,
info: &PoolCreateInfo,
chain: AllocationChain<'device>,
) -> Result<Pool, AllocError>
pub unsafe fn create_pool_with_chain( &self, info: &PoolCreateInfo, chain: AllocationChain<'device>, ) -> Result<Pool, AllocError>
Run Allocator::create_pool_with_chain under this allocator’s lock.
§Errors
Same checked/native errors as Allocator::create_pool_with_chain, plus SynchronizationPoisoned.
§Safety
Same retained-chain contract as Allocator::create_pool_with_chain;
the chain must also satisfy SynchronizedAllocator::new’s any-thread rules.
Sourcepub fn destroy_pool(&self, pool: &mut Pool) -> Result<(), AllocError>
pub fn destroy_pool(&self, pool: &mut Pool) -> Result<(), AllocError>
Run Allocator::destroy_pool under this allocator’s lock.
§Errors
Same live-resource errors as Allocator::destroy_pool, plus SynchronizationPoisoned.
Sourcepub fn pool_statistics(&self, pool: &Pool) -> Result<PoolStats, AllocError>
pub fn pool_statistics(&self, pool: &Pool) -> Result<PoolStats, AllocError>
One pool’s statistics under this allocator’s lock.
§Errors
Same errors as Allocator::pool_statistics, plus SynchronizationPoisoned.
Sourcepub fn set_pool_name(
&self,
pool: &Pool,
name: Option<&str>,
) -> Result<(), AllocError>
pub fn set_pool_name( &self, pool: &Pool, name: Option<&str>, ) -> Result<(), AllocError>
Run Allocator::set_pool_name under this allocator’s lock.
§Errors
Same errors as Allocator::set_pool_name, plus SynchronizationPoisoned.
Sourcepub fn set_preferred_block_size(&self, size: u64) -> Result<(), AllocError>
pub fn set_preferred_block_size(&self, size: u64) -> Result<(), AllocError>
Run Allocator::set_preferred_block_size under this allocator’s lock.
§Errors
Same errors as Allocator::set_preferred_block_size, plus SynchronizationPoisoned.
Sourcepub fn set_mapping_hysteresis(&self, enabled: bool) -> Result<(), AllocError>
pub fn set_mapping_hysteresis(&self, enabled: bool) -> Result<(), AllocError>
Run Allocator::set_mapping_hysteresis under this allocator’s lock.
§Errors
Same errors as Allocator::set_mapping_hysteresis, plus SynchronizationPoisoned.
Sourcepub fn detailed_statistics(&self) -> Result<MemoryStatistics, AllocError>
pub fn detailed_statistics(&self) -> Result<MemoryStatistics, AllocError>
Aggregate memory statistics under this allocator’s lock.
§Errors
Same errors as Allocator::detailed_statistics, plus SynchronizationPoisoned.
Sourcepub fn detailed_pool_statistics(
&self,
pool: &Pool,
) -> Result<DetailedStatistics, AllocError>
pub fn detailed_pool_statistics( &self, pool: &Pool, ) -> Result<DetailedStatistics, AllocError>
One pool’s detailed statistics under this allocator’s lock.
§Errors
Same errors as Allocator::detailed_pool_statistics, plus SynchronizationPoisoned.
Sourcepub fn write_statistics_json(
&self,
output: &mut impl Write,
detailed: bool,
) -> Result<(), AllocError>
pub fn write_statistics_json( &self, output: &mut impl Write, detailed: bool, ) -> Result<(), AllocError>
Run Allocator::write_statistics_json under this allocator’s lock.
§Errors
Same errors as Allocator::write_statistics_json, plus SynchronizationPoisoned.
Sourcepub fn set_debug_memory_settings(
&self,
settings: DebugMemorySettings,
) -> Result<(), AllocError>
pub fn set_debug_memory_settings( &self, settings: DebugMemorySettings, ) -> Result<(), AllocError>
Run Allocator::set_debug_memory_settings under this allocator’s lock.
§Errors
Same errors as Allocator::set_debug_memory_settings, plus SynchronizationPoisoned.
Sourcepub unsafe fn check_corruption(&self, bits: u32) -> Result<(), AllocError>
pub unsafe fn check_corruption(&self, bits: u32) -> Result<(), AllocError>
Sourcepub unsafe fn check_pool_corruption(
&self,
pool: &Pool,
) -> Result<(), AllocError>
pub unsafe fn check_pool_corruption( &self, pool: &Pool, ) -> Result<(), AllocError>
Sourcepub unsafe fn set_external_memory_types(
&self,
types: &[ExternalMemoryHandleTypeFlags],
) -> Result<(), AllocError>
pub unsafe fn set_external_memory_types( &self, types: &[ExternalMemoryHandleTypeFlags], ) -> Result<(), AllocError>
Sourcepub fn external_memory_types(
&self,
allocation: &Allocation,
) -> Result<ExternalMemoryHandleTypeFlags, AllocError>
pub fn external_memory_types( &self, allocation: &Allocation, ) -> Result<ExternalMemoryHandleTypeFlags, AllocError>
One allocation’s external handle types under this allocator’s lock.
§Errors
Same errors as Allocator::external_memory_types, plus SynchronizationPoisoned.
Sourcepub unsafe fn get_memory_fd(
&self,
allocation: &Allocation,
handle_type: ExternalMemoryHandleTypeFlagBits,
) -> Result<RawFd, AllocError>
pub unsafe fn get_memory_fd( &self, allocation: &Allocation, handle_type: ExternalMemoryHandleTypeFlagBits, ) -> Result<RawFd, AllocError>
Sourcepub unsafe fn set_device_memory_callbacks(
&self,
callbacks: Option<&'device DeviceMemoryCallbacks>,
) -> Result<(), AllocError>
pub unsafe fn set_device_memory_callbacks( &self, callbacks: Option<&'device DeviceMemoryCallbacks>, ) -> Result<(), AllocError>
Run Allocator::set_device_memory_callbacks under this allocator’s lock.
§Errors
Same errors as Allocator::set_device_memory_callbacks, plus SynchronizationPoisoned.
§Safety
Same retained-callback contract as Allocator::set_device_memory_callbacks;
callbacks must also satisfy SynchronizedAllocator::new’s any-thread rules.
Source§impl<'device> SynchronizedAllocator<'device>
impl<'device> SynchronizedAllocator<'device>
Sourcepub unsafe fn new(allocator: Allocator<'device>) -> Self
pub unsafe fn new(allocator: Allocator<'device>) -> Self
Adopt one allocator for synchronized access from any host thread. No native operation, allocation, mapping or thread is started.
§Safety
Every retained callback record/code/user datum, pool allocation chain and nested external reference must remain valid for the device borrow and support access on any participating thread, including final CPU cleanup. Retained records must be immutable across threads; callback-owned mutable state needs its own synchronization when shared with independent owners. Existing mapped-byte uses must be synchronized against subsequent operations. Native contexts must meet Vulkan’s host-thread lifetime/valid-usage contract. No callback may unwind or reenter this same allocator.
Sourcepub fn new_owned(allocator: Allocator<'static>) -> Self
pub fn new_owned(allocator: Allocator<'static>) -> Self
Adopt one device-retained allocator for synchronized access from any
host thread. Every retained reference is owned or 'static, so the
unsafe contract of Self::new is satisfied by construction; the
remaining caller obligations are the documented host-thread,
non-reentrancy and mapped-byte synchronization rules.
Sourcepub unsafe fn with_allocator<R>(
&self,
operation: impl FnOnce(&mut Allocator<'device>) -> R,
) -> Result<R, AllocError>
pub unsafe fn with_allocator<R>( &self, operation: impl FnOnce(&mut Allocator<'device>) -> R, ) -> Result<R, AllocError>
Run one operation/batch with exclusive access to the canonical allocator. The borrow cannot escape the closure. Returned tokens/handles remain raw native identities; no lock covers their later GPU or mapped-byte uses.
§Errors
Returns SynchronizationPoisoned without running the closure after a panic. Operation errors remain the closure’s result and do not poison the mutex.
§Panics
A closure panic propagates and poisons subsequent access. Reentrant use of this same allocator can deadlock and violates the unsafe access contract.
§Safety
Preserve new’s any-thread contract for every retained registration/state change. Do not replace the allocator with thread-affine state. All native operation/callback/completion rules apply. Inside any partitioned scope, never move out or replace the borrowed child allocator. Synchronize any escaping mapped pointer before unmap/free/relocation; the mutex protects metadata only.
Sourcepub unsafe fn try_with_allocator<R>(
&self,
operation: impl FnOnce(&mut Allocator<'device>) -> R,
) -> Result<Option<R>, AllocError>
pub unsafe fn try_with_allocator<R>( &self, operation: impl FnOnce(&mut Allocator<'device>) -> R, ) -> Result<Option<R>, AllocError>
Attempt one exclusive operation without waiting for another host user.
None means busy; poison is an error and never bypassed.
§Errors
Same poison refusal as with_allocator; operation failures stay in R.
§Safety
The complete with_allocator contract applies, including any-thread retained state, callback non-reentrancy and synchronization of escaping mappings.
Sourcepub unsafe fn with_pools<R>(
&self,
pools: &[&Pool],
operation: impl FnOnce(&[Self]) -> R,
) -> Result<R, AllocError>
pub unsafe fn with_pools<R>( &self, pools: &[&Pool], operation: impl FnOnce(&[Self]) -> R, ) -> Result<R, AllocError>
Run independent custom pools concurrently through borrowed child owners.
Children correspond to pools in input order, preserve allocation/pool
identities and use the same canonical methods through with_allocator.
Each child serializes its own pool; different pools can execute native
operations concurrently, even on the same memory type. A shared reservation
lock enforces aggregate native-count, heap and within-budget limits, but
never covers native PFNs. The parent remains locked for the whole scope.
Its ordinary operations, statistics and relocation resume after restoration.
All scope metadata uses the allocator’s CPU callbacks. Merge capacity is reserved before native effects; scope exit and panic restoration allocate no host memory and perform no native cleanup. Existing mappings remain live. Budget pressure is sampled at entry and corrected for all local reservations through this batch; split long-lived workloads into bounded scopes to refresh.
// SAFETY: all retained references/callbacks support concurrent workers;
// this batch installs no thread-affine state and leaves native cleanup explicit.
unsafe { shared.with_pools(&[first, second], |children| {
std::thread::scope(|scope| {
for (child, pool) in children.iter().zip([first, second]) {
scope.spawn(move || child.with_allocator(|allocator| {
allocator.pool_statistics(pool)
}).unwrap().unwrap());
}
});
})?; }§Errors
Rejects foreign/stale/duplicate pools, nested pool scopes, preparation OOM, and poisoned access. A child panic poisons the parent even if caught by the operation. Cached export-root ownership follows its backing memory across the scope.
§Safety
The complete with_allocator contract applies to every child. Use only
its selected pool for allocations; allocator-wide changes are rejected.
Never replace, move out or retain a child’s allocator/context. All borrowed
workers must finish before returning; do not reenter the locked parent.
Synchronize shared callbacks/user data across pools. Mapped-byte and GPU
ownership/completion remain explicit, including after a worker panic.
Sourcepub unsafe fn with_memory_types<R>(
&self,
memory_types: &[u32],
operation: impl FnOnce(&[Self]) -> R,
) -> Result<R, AllocError>
pub unsafe fn with_memory_types<R>( &self, memory_types: &[u32], operation: impl FnOnce(&[Self]) -> R, ) -> Result<R, AllocError>
Run independent default memory-type vectors concurrently.
Children correspond to distinct native memory-type indices. They own only default storage of that type, including separate allocations and cached blocks; custom pools remain with the parent. Native type selection cannot escape its selected type. Tokens/maps and accounting retain parent identity.
// SAFETY: retained device/callback state supports these joined workers;
// no replacement, registration or mapped byte access occurs in this batch.
unsafe { shared.with_memory_types(&[0], |children| {
std::thread::scope(|scope| {
scope.spawn(|| children[0].with_allocator(|allocator| {
allocator.memory_type_properties(0)
}).unwrap().unwrap()).join().unwrap();
});
})?; }§Errors
Rejects absent/duplicate types, nested scopes, poison and metadata OOM.
§Safety
The complete with_pools worker/callback/native-lifetime contract applies.
Use default allocation policies, without a custom pool. Never move out or
replace child owners, reenter the parent or form cross-child lock cycles.
Sourcepub unsafe fn with_blocks<R>(
&self,
allocations: &[&Allocation],
operation: impl FnOnce(&[Self]) -> R,
) -> Result<R, AllocError>
pub unsafe fn with_blocks<R>( &self, allocations: &[&Allocation], operation: impl FnOnce(&[Self]) -> R, ) -> Result<R, AllocError>
Run mapping/cache/binding work concurrently on distinct native blocks.
Each seed is a live allocation; seeds must select different backing memory objects. A child contains every live region on that backing object, including regions not used as seeds. Regions sharing a block share its one mutex/map count. Different blocks of one custom/default pool can progress independently. Allocation/free, pool changes, trim and relocation are excluded for this borrowed phase. Map holds, metadata, cached exports and original block order return to the parent, including after panic. No native cleanup occurs on exit. A child borrow cannot escape this phase:
let child = unsafe { shared.with_blocks(&[seed], |children| &children[0]) };§Errors
Rejects stale/foreign seeds, duplicate backings, nested scopes, poison and OOM.
§Safety
The complete with_pools borrowing/any-thread/native contract applies.
Use each token only in its matching child. No worker/reference may escape;
synchronize mapped bytes and external object uses, and avoid lock cycles.
Sourcepub fn statistics(&self) -> Result<AllocatorStats, AllocError>
pub fn statistics(&self) -> Result<AllocatorStats, AllocError>
Observe a serialized allocator-owned statistics snapshot.
§Errors
Returns SynchronizationPoisoned after a closure panic.
Sourcepub fn into_inner(
self,
) -> Result<Allocator<'device>, PoisonError<Allocator<'device>>>
pub fn into_inner( self, ) -> Result<Allocator<'device>, PoisonError<Allocator<'device>>>
Recover the exclusive allocator without performing native cleanup.
§Errors
PoisonError retains the allocator for deliberate inspection/recovery using into_inner; do not assume panic-interrupted native transactions completed.