1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
//! A steamy river of uring. Fast IO with a API that doesn't make me eyes bleed. GPL-666'd. //! //! # Examples //! //! # Really shines with O_DIRECT: //! ``` //! use std::{ //! fs::OpenOptions, //! io::{IoSlice, IoSliceMut, Result}, //! os::unix::fs::OpenOptionsExt, //! }; //! //! const CHUNK_SIZE: u64 = 4096 * 256; //! //! // `O_DIRECT` requires all reads and writes //! // to be aligned to the block device's block //! // size. 4096 might not be the best, or even //! // a valid one, for yours! //! #[repr(align(4096))] //! struct Aligned([u8; CHUNK_SIZE as usize]); //! //! fn main() -> Result<()> { //! // start the ring //! let mut ring = rio::new().expect("create uring"); //! //! // open output file, with `O_DIRECT` set //! let file = OpenOptions::new() //! .read(true) //! .write(true) //! .create(true) //! .truncate(true) //! .custom_flags(libc::O_DIRECT) //! .open("file") //! .expect("open file"); //! //! // create output buffer //! let out_buf = Aligned([42; CHUNK_SIZE as usize]); //! let out_io_slice = IoSlice::new(&out_buf.0); //! //! // create input buffer //! let mut in_buf = Aligned([0; CHUNK_SIZE as usize]); //! let mut in_io_slice = IoSliceMut::new(&mut in_buf.0); //! //! let mut completions = vec![]; //! //! for i in 0..(4 * 1024) { //! let at = i * CHUNK_SIZE; //! //! // Write using `Ordering::Link`, //! // causing the next operation to wait //! // for the this operation //! // to complete before starting. //! // //! // If this operation does not //! // fully complete, the next linked //! // operation fails with `ECANCELED`. //! // //! // io_uring executes unchained //! // operations out-of-order to //! // improve performance. It interleaves //! // operations from different chains //! // to improve performance. //! let completion = ring.write_ordered( //! &file, //! &out_io_slice, //! at, //! rio::Ordering::Link, //! )?; //! completions.push(completion); //! //! let completion = //! ring.read(&file, &mut in_io_slice, at)?; //! completions.push(completion); //! } //! //! ring.submit_all()?; //! //! let mut canceled = 0; //! for completion in completions.into_iter() { //! match completion.wait() { //! Err(e) if e.raw_os_error() == Some(125) => { //! canceled += 1 //! } //! Ok(_) => {} //! other => panic!("error: {:?}", other), //! } //! } //! //! Ok(()) //! } //! ``` use std::io; mod completion; mod fastlock; #[cfg(target_os = "linux")] mod io_uring; #[cfg(target_os = "linux")] pub use io_uring::{Ordering, Uring as Rio}; pub use completion::Completion; use { completion::{pair, CompletionFiller}, fastlock::FastLock, }; /// Create a new IO system. pub fn new() -> io::Result<Rio> { Rio::new(256) }