pub struct Rdma { /* private fields */ }
Expand description

Rdma handler, the only interface that the users deal with rdma

Implementations

Send the content in the lm

Used with receive. Application scenario such as: client put data into a local mr and send to server. Server receive the mr sent by client and process data in it.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // send the content of lmr to server
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data sent by client and put it into an mr
    let lmr = rdma.receive().await?;
    // read data from mr
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(lmr.as_ptr() as *const Data)).0
        )
    };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Send the content in the lm with immediate date.

Used with receive_with_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);
static IMM_NUM: u32 = 123;
static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { std::ptr::write(lmr.as_mut_ptr() as *mut Data, Data(MSG.to_string())) };
    // send the content of lmr and imm data to server
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send(&lmr).await?;
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data and imm sent by the client
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, Some(IMM_NUM));
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // receive the data in mr while avoiding the immediate data is ok.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // `receive_with_imm` works well even if the client didn't send any immediate data.
    // the imm received will be a `None`.
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, None);
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // compared to the above, using `receive` is a better choice.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Receive the content and stored in the returned memory region

Used with send. Application scenario such as: client put data into a local mr and send to server. Server receive the mr sent by client and process data in it.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // send the content of lmr to server
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data sent by client and put it into an mr
    let lmr = rdma.receive().await?;
    // read data from mr
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(lmr.as_ptr() as *const Data)).0
        )
    };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Receive the content and stored in the returned memory region.

Used with send_with_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);
static IMM_NUM: u32 = 123;
static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { std::ptr::write(lmr.as_mut_ptr() as *mut Data, Data(MSG.to_string())) };
    // send the content of lmr and imm data to server
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send(&lmr).await?;
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data and imm sent by the client
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, Some(IMM_NUM));
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // receive the data in mr while avoiding the immediate data is ok.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // `receive_with_imm` works well even if the client didn't send any immediate data.
    // the imm received will be a `None`.
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, None);
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // compared to the above, using `receive` is a better choice.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Receive the immediate data sent by write_with_imm.

Used with write_with_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

static IMM_NUM: u32 = 123;
struct Data(String);

static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    let data = Data(MSG.to_string());
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = data };
    // write the content of lmr to remote mr with immediate data.
    rdma.write_with_imm(&lmr, &mut rmr, IMM_NUM).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the immediate data sent by `write_with_imm`
    let imm = rdma.receive_write_imm().await?;
    assert_eq!(imm, IMM_NUM);
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Read content in the rm and store the content in the lm

Application scenario such as: client put data into a local mr and send_mr to server. Server get a remote mr by receive_remote_mr, and then get data from this rmr by rdma read.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // then send the metadata of this lmr to server to make server aware of this mr.
    rdma.send_local_mr(lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // receive the metadata of rmr sent by client
    let rmr = rdma.receive_remote_mr().await?;
    // `read` data from rmr to lmr
    rdma.read(&mut lmr, &rmr).await?;
    // assert the content of lmr, which was get from rmr by rdma `read`
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(lmr.as_ptr() as *const Data)).0
        )
    };
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Write content in the lm to rm

Application scenario such as: client request a remote mr through request_remote_mr, and then put data into this rmr by rdma write. After all client send_mr to make server aware of this mr. After client send_mr, server receive_local_mr, and then get data from this mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // put data into lmr
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // write the content of local mr into remote mr
    rdma.write(&lmr, &mut rmr).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(lmr.as_ptr() as *const Data)).0
        )
    };
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Write content in the lm to rm and send a immediate data which will consume a rdma receive work request in the receiver’s receive queue. The receiver can receive this immediate data by using receive_write_imm.

Used with receive_write_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

static IMM_NUM: u32 = 123;
struct Data(String);

static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    let data = Data(MSG.to_string());
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = data };
    // write the content of lmr to server with immediate data.
    rdma.write_with_imm(&lmr, &mut rmr, IMM_NUM).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the immediate data sent by `write_with_imm`
    let imm = rdma.receive_write_imm().await?;
    assert_eq!(imm, IMM_NUM);
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe { assert_eq!(MSG.to_string(), *(*(lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Connect the remote endpoint and build rmda queue pair by TCP connection

gid_index: 0:ipv6, 1:ipv4 max_message_length: max length of msg used in send&receive.

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let _rdma = Rdma::connect(addr, 1, 1, 512).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let _rdma = rdma_listener.accept(1, 1, 512).await?;
    // run here after client connect
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Allocate a local memory region

You can use local mr to send&receive or read&write with a remote mr. The parameter layout can be obtained by Layout::new::<Data>(). You can learn the way to write or read data in mr in the following example.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // send the content of lmr to server
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data sent by client and put it into an mr
    let lmr = rdma.receive().await?;
    // assert data in the lmr
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(lmr.as_ptr() as *const Data)).0
        )
    };
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Request a remote memory region

Used with send_mr, receive_local_mr, read and write. Application scenario such as: client uses request_remote_mr to apply for a remote mr from server, and makes server aware of this mr by send_mr to server. For server, this mr is a local mr, which can be received through receive_local_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // do something with rmr like `write` data into it.
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // do something with lmr like getting data from it.
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Send a local memory region metadata to remote

Used with receive_remote_mr

Application scenario such as: client uses alloc_local_mr to alloc a local mr, and makes server aware of this mr by send_local_mr to server. For server, this mr is a remote mr, which can be received through receive_remote_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use std::{alloc::Layout, sync::Arc, io, time::Duration, net::{Ipv4Addr, SocketAddrV4}};
use portpicker::pick_unused_port;
use crate::async_rdma::{ LocalMrWriteAccess, LocalMrReadAccess };

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // do something with rmr like `write` data into it.
    // then send the metadata of this lmr to server to make server aware of this mr.
    rdma.send_local_mr(lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of rmr sent by client
    let rmr = rdma.receive_remote_mr().await?;
    // do something with lmr like getting data from it.
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr).await.map_err(|err| println!("{}", err)).unwrap();
}

Send a remote memory region metadata to remote

Used with receive_local_mr.

Application scenario such as: client uses request_remote_mr to apply for a remote mr from server, and makes server aware of this mr by send_remote_mr to server. For server, this mr is a local mr, which can be received through receive_local_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use std::{alloc::Layout, sync::Arc, io, time::Duration, net::{Ipv4Addr, SocketAddrV4}};
use portpicker::pick_unused_port;
use crate::async_rdma::{ LocalMrWriteAccess, LocalMrReadAccess };

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // do something with rmr like `write` data into it.
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // do something with lmr like getting data from it.
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr).await.map_err(|err| println!("{}", err)).unwrap();
}

Receive a local memory region

Used with send_mr. Application scenario such as: client uses request_remote_mr to apply for a remote mr from server, and makes server aware of this mr by send_mr to server. For server, this mr is a local mr, which can be received through receive_local_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples

Application scenario such as: client request a remote mr through request_remote_mr, and then put data into this rmr by rdma write. After all client send_mr to make server aware of this mr. After client send_mr, server receive_local_mr, and then get data from this mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // put data into lmr
    unsafe { *(lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // write the content of local mr into remote mr
    rdma.write(&lmr, &mut rmr).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe {
        assert_eq!(
        "hello world".to_string(),
        *(*(lmr.as_ptr() as *const Data)).0
    )
    };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Receive a remote memory region

Used with send_mr. Application scenario such as: server alloc a local mr and put data into it and let client know about this mr through send_mr. For client, this is a remote mr located in server.Client receive the metadata of this mr by receive_remote_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // receive the metadata of rmr sent by client
    let _rmr = rdma.receive_remote_mr().await?;
    // do something with rmr like `read` data from it.
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    let lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // do something with lmr like put data into it.
    // then send the metadata of this lmr to server to make server aware of this mr.
    rdma.send_local_mr(lmr).await?;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more

Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

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

The alignment of pointer.

The type for initializers.

Initializes a with the given initializer. Read more

Dereferences the given pointer. Read more

Mutably dereferences the given pointer. Read more

Drops the object pointed to by the given pointer. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more