Skip to main content

PlatformIvc

Trait PlatformIvc 

Source
pub trait PlatformIvc {
    // Required methods
    fn channel_get(id: u32) -> *mut c_void;
    fn frame_size(ch: *mut c_void) -> u32;
    fn rx_get(ch: *mut c_void, len_out: *mut usize) -> *const u8;
    fn rx_release(ch: *mut c_void);
    fn tx_get(ch: *mut c_void, cap_out: *mut usize) -> *mut u8;
    fn tx_commit(ch: *mut c_void, len: usize);
    fn tx_abandon(ch: *mut c_void);
    fn notify(ch: *mut c_void);
}
Expand description

Inter-processor mailbox transport, modelled after NVIDIA Tegra IVC.

IVC (Inter-VM Communication on Tegra; in practice CCPLEX↔SPE on AGX Orin) is a header-prefixed lock-free SPSC ring in shared DRAM, paired with a hardware doorbell for wake. One channel is one peer — there is no discovery, naming, QoS, or fanout — which is why it’s a link transport (peer to TCP/UDP/Serial/RawEth inside zenoh-pico) rather than a new RMW backend.

Channel handles are opaque *mut c_void to match the shape zenoh-pico passes across its FFI boundary. The driver crate (nvidia-ivc) translates between this opaque handle and either NVIDIA’s FSP tegra_ivc_* API (fsp feature) or a Unix-socket pair (unix-mock feature, host dev + CI).

Zero-copy contract (Phase 11.3.A). NVIDIA’s FSP IVC API is fundamentally a “borrow ring slot, fill, commit / release” pattern. Both backends mirror that here so consumers don’t branch on backend:

  • Self::rx_get returns a pointer into the channel’s RX slot (and writes the frame length to *len_out); Self::rx_release advances the producer-visible cursor. Returns null + *len_out = 0 if the ring is empty.
  • Self::tx_get returns a writable pointer to the next free TX slot (and writes the slot capacity to *cap_out); Self::tx_commit makes the slot visible to the peer (and rings the per-frame doorbell on FSP — see notify for batching). Self::tx_abandon frees the slot without sending. Returns null + *cap_out = 0 if the ring is full.

Single outstanding RX slot and single outstanding TX slot per channel — borrow, finish, repeat. Multi-frame batching is the caller’s job (loop tx_get / fill / tx_commit, then one notify).

frame_size is the fixed per-channel frame size negotiated at carveout setup (typical NVIDIA IVC: 64 bytes per frame, 16 frames per channel). The link layer uses it to pick its reassembly buffer.

Required Methods§

Source

fn channel_get(id: u32) -> *mut c_void

Resolve a channel ID into an opaque handle. Returns null on failure. The numeric ID matches the NVIDIA channel index (channel 2 = aon_echo).

Source

fn frame_size(ch: *mut c_void) -> u32

Fixed frame size negotiated for this channel, in bytes.

Source

fn rx_get(ch: *mut c_void, len_out: *mut usize) -> *const u8

Borrow the next-available RX frame. Writes the frame length to *len_out and returns a pointer into the ring. Returns null + *len_out = 0 if no frame is available.

Source

fn rx_release(ch: *mut c_void)

Release the most recently rx_get’d frame back to the producer. Pair 1:1 with rx_get calls that returned non-null.

Source

fn tx_get(ch: *mut c_void, cap_out: *mut usize) -> *mut u8

Borrow the next free TX slot. Writes the slot capacity to *cap_out and returns a writable pointer. Returns null + *cap_out = 0 if the ring is full.

Source

fn tx_commit(ch: *mut c_void, len: usize)

Commit len bytes from the most recently tx_get’d slot. Slot is then visible to the peer; per-frame doorbell may also fire on FSP. Pair 1:1 with tx_get calls that returned non-null.

Source

fn tx_abandon(ch: *mut c_void)

Abandon the most recently tx_get’d slot without sending. Pair 1:1 with tx_get calls that returned non-null.

Source

fn notify(ch: *mut c_void)

Ring the doorbell. On FSP this is redundant (commit/release already invoke ch->notify_remote); on unix-mock it’s a no-op (SOCK_DGRAM wakes the peer naturally). Provided for symmetry so callers can batch-commit then notify once.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§