pub struct KeepaliveLocalMemory { /* private fields */ }Expand description
Local memory handle that keeps its backing allocation alive via an
Arc<dyn Keepalive>.
Detects at construction time whether the address is a CUDA device
pointer and dispatches read_at/write_at accordingly.
All three access methods are unsafe: the Keepalive only
guarantees the allocation stays mapped, not that this handle has
unique ownership. The internal [AccessLock] coordinates concurrent
callers that share the same clone of this handle (readers run in
parallel, exclusive writers run alone, disjoint writers run in
parallel with one another but exclude readers and exclusive
writers), but callers must additionally rule out concurrent access
through other views of the same allocation.
The direct_access_host_bandwidth and direct_access_device_bandwidth
fields indicate the speed of reading the memory via pointer dereference
on a host or device thread, respectively. A value of None means the
memory is not directly accessible from that context.
Implementations§
Source§impl KeepaliveLocalMemory
impl KeepaliveLocalMemory
Sourcepub fn new(addr: usize, size: usize, keepalive: Arc<dyn Keepalive>) -> Self
pub fn new(addr: usize, size: usize, keepalive: Arc<dyn Keepalive>) -> Self
Create a new handle. Probes the CUDA driver to determine whether
addr is a device pointer and sets the bandwidth fields
accordingly.
Sourcepub unsafe fn read_at(&self, offset: usize, dst: &mut [u8]) -> Result<(), Error>
pub unsafe fn read_at(&self, offset: usize, dst: &mut [u8]) -> Result<(), Error>
Copy dst.len() bytes from this memory region starting at offset
into dst.
Mutually exclusive with both write_at and write_at_disjoint
across clones of this handle: the [AccessLock] guarantees a
reader and any writer (exclusive or disjoint) that share the
same lock never observe each other’s partial state. Multiple
concurrent read_at calls on shared clones are permitted and
run in parallel.
§Safety
The Keepalive guarantees the allocation stays mapped, but it
does not imply unique ownership: another component may hold its
own view of the same allocation and read or write it concurrently
outside this handle’s [AccessLock]. The caller must ensure that
no such external access produces a torn read of
offset..offset + dst.len() for the duration of this call.
Sourcepub unsafe fn write_at(&self, offset: usize, src: &[u8]) -> Result<(), Error>
pub unsafe fn write_at(&self, offset: usize, src: &[u8]) -> Result<(), Error>
Copy src.len() bytes from src into this memory region starting
at offset.
Mutually exclusive with every other read and write against this
region across clones of this handle: the [AccessLock] blocks
concurrent readers and writers that share the same lock. Use
KeepaliveLocalMemory::write_at_disjoint when multiple writers
can be proven to target disjoint byte ranges.
§Safety
See KeepaliveLocalMemory::read_at. The Keepalive guarantee
covers liveness only; the caller must ensure no concurrent
external reader or writer observes an overlapping byte range.
Sourcepub unsafe fn write_at_disjoint(
&self,
offset: usize,
src: &[u8],
) -> Result<(), Error>
pub unsafe fn write_at_disjoint( &self, offset: usize, src: &[u8], ) -> Result<(), Error>
Like KeepaliveLocalMemory::write_at, but allows other
concurrent write_at_disjoint calls (across clones of this
handle) to proceed in parallel. Still mutually exclusive with
read_at and write_at through the [AccessLock].
§Safety
In addition to the obligations of
KeepaliveLocalMemory::write_at (no external concurrent
reader or writer of the same byte range), the caller must
ensure that no other concurrent call to this method targets a
byte range that overlaps offset..offset + src.len(). Disjoint
byte ranges across concurrent disjoint callers are sound.
Trait Implementations§
Source§impl Clone for KeepaliveLocalMemory
impl Clone for KeepaliveLocalMemory
Source§fn clone(&self) -> KeepaliveLocalMemory
fn clone(&self) -> KeepaliveLocalMemory
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for KeepaliveLocalMemory
impl !RefUnwindSafe for KeepaliveLocalMemory
impl Send for KeepaliveLocalMemory
impl Sync for KeepaliveLocalMemory
impl Unpin for KeepaliveLocalMemory
impl UnsafeUnpin for KeepaliveLocalMemory
impl !UnwindSafe for KeepaliveLocalMemory
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<A, M> Handler<IndexedErasedUnbound<M>> for A
impl<A, M> Handler<IndexedErasedUnbound<M>> for A
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].