Skip to content

Commit

Permalink
📝 add linux aio bindings (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xudong-Huang committed Mar 7, 2019
1 parent 147e59b commit 968e65d
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@ lto = true
[build-dependencies]
rustc_version = "0.2"

[target.'cfg(target_os = "linux")'.build-dependencies]
bindgen = "0.48"

[workspace]
members = ["may_queue"]
29 changes: 29 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
#[cfg(target_os = "linux")]
extern crate bindgen;
extern crate rustc_version;

use rustc_version::{version_meta, Channel};

#[cfg(target_os = "linux")]
fn gen_linux_aio_bindings() {
use std::env;
use std::path::PathBuf;
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
.trust_clang_mangling(false)
// The input header we would like to generate
// bindings for.
.header("linux_aio_wrapper.h")
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");

// Write the bindings to the $OUT_DIR/linux_bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("linux_bindings.rs"))
.expect("Couldn't write linux_bindings.rs!");
}

fn main() {
// Set cfg flags depending on release channel
if let Channel::Nightly = version_meta().unwrap().channel {
println!("cargo:rustc-cfg=nightly");
}

#[cfg(target_os = "linux")]
gen_linux_aio_bindings();
}
6 changes: 6 additions & 0 deletions linux_aio_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <time.h>
#include <unistd.h>
#include <linux/aio_abi.h>
#include <sys/eventfd.h>
#include <sys/syscall.h>

1 change: 0 additions & 1 deletion src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ impl File {
});
}
}
dbg!(path.as_ref());
let file = fs_impl::create(path)?;
File::from(file)
}
Expand Down
2 changes: 1 addition & 1 deletion src/io/sys/unix/fs/fs_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct FileRead<'a> {
}

impl<'a> FileRead<'a> {
pub fn new<T: AsIoData>(s: &'a T, offset: u64, buf: &'a mut [u8]) -> Self {
pub fn new<T: AsIoData>(s: &'a T, _offset: u64, buf: &'a mut [u8]) -> Self {
FileRead {
io_data: s.as_io_data(),
buf,
Expand Down
2 changes: 1 addition & 1 deletion src/io/sys/unix/fs/fs_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct FileWrite<'a> {
}

impl<'a> FileWrite<'a> {
pub fn new<T: AsIoData>(s: &'a T, offset: u64, buf: &'a [u8]) -> Self {
pub fn new<T: AsIoData>(s: &'a T, _offset: u64, buf: &'a [u8]) -> Self {
FileWrite {
io_data: s.as_io_data(),
buf,
Expand Down
82 changes: 82 additions & 0 deletions src/io/sys/unix/linux_aio_bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#![allow(dead_code)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

include!(concat!(env!("OUT_DIR"), "/linux_bindings.rs"));

/*
* extracted from https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/fs.h#L372
* Flags for preadv2/pwritev2:
*/

/* per-IO O_DSYNC */
//#define RWF_DSYNC ((__force __kernel_rwf_t)0x00000002)
pub const RWF_DSYNC: u32 = 2;

/* per-IO O_SYNC */
//#define RWF_SYNC ((__force __kernel_rwf_t)0x00000004)
pub const RWF_SYNC: u32 = 4;

/* per-IO, return -EAGAIN if operation would block */
//#define RWF_NOWAIT ((__force __kernel_rwf_t)0x00000008)
pub const RWF_NOWAIT: u32 = 8;


pub use libc::c_long;

// Relevant symbols from the native bindings exposed via aio-bindings
// pub use self::{aio_context_t, io_event, iocb, syscall, timespec,
// __NR_io_destroy, __NR_io_getevents, __NR_io_setup, __NR_io_submit,
// IOCB_CMD_PREAD, IOCB_CMD_PWRITE, IOCB_CMD_FSYNC, IOCB_CMD_FDSYNC, IOCB_FLAG_RESFD,
// RWF_DSYNC, RWF_SYNC};

// -----------------------------------------------------------------------------------------------
// Inline functions that wrap the kernel calls for the entry points corresponding to Linux
// AIO functions
// -----------------------------------------------------------------------------------------------

// Initialize an AIO context for a given submission queue size within the kernel.
//
// See [io_setup(7)](http://man7.org/linux/man-pages/man2/io_setup.2.html) for details.
#[inline(always)]
pub unsafe fn io_setup(nr: c_long, ctxp: *mut aio_context_t) -> c_long {
syscall(__NR_io_setup as c_long, nr, ctxp)
}

// Destroy an AIO context.
//
// See [io_destroy(7)](http://man7.org/linux/man-pages/man2/io_destroy.2.html) for details.
#[inline(always)]
pub unsafe fn io_destroy(ctx: aio_context_t) -> c_long {
syscall(__NR_io_destroy as c_long, ctx)
}

// Submit a batch of IO operations.
//
// See [io_sumit(7)](http://man7.org/linux/man-pages/man2/io_submit.2.html) for details.
#[inline(always)]
pub unsafe fn io_submit(ctx: aio_context_t, nr: c_long, iocbpp: *mut *mut iocb) -> c_long {
syscall(__NR_io_submit as c_long, ctx, nr, iocbpp)
}

// Retrieve completion events for previously submitted IO requests.
//
// See [io_getevents(7)](http://man7.org/linux/man-pages/man2/io_getevents.2.html) for details.
#[inline(always)]
pub unsafe fn io_getevents(
ctx: aio_context_t,
min_nr: c_long,
max_nr: c_long,
events: *mut io_event,
timeout: *mut timespec,
) -> c_long {
syscall(
__NR_io_getevents as c_long,
ctx,
min_nr,
max_nr,
events,
timeout,
)
}
3 changes: 3 additions & 0 deletions src/io/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#[path = "epoll.rs"]
mod select;

#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux_aio_bindings;

#[cfg(any(
target_os = "bitrig",
target_os = "dragonfly",
Expand Down

0 comments on commit 968e65d

Please sign in to comment.