diff --git a/demos/rust/.gitignore b/demos/rust/.gitignore new file mode 100644 index 00000000..1ad1a25d --- /dev/null +++ b/demos/rust/.gitignore @@ -0,0 +1,3 @@ +occlum_instance +target +Cargo.lock diff --git a/demos/rust/README.md b/demos/rust/README.md index 69051136..821412a5 100644 --- a/demos/rust/README.md +++ b/demos/rust/README.md @@ -11,9 +11,9 @@ Refer to tools/toolchains/rust/build.sh for more information. ## rust\_app -This directory contains source code of a Rust program with a cpp FFI. The cpp -interface increments the input by one. Rust code calls the function and -displays the result on the terminal. +This directory contains source code of a Rust program with two test cases. One is a cpp FFI test, +where the cpp interface increments the input by one. The other is a multithreading file backed mmap test. +Rust code calls the function and displays the result on the terminal. One can use occlum-cargo in the way cargo is used. In the rust\_app directory, calling ```occlum-cargo build``` will build the demo and ```occlum-cargo run``` @@ -23,5 +23,6 @@ run_rust_demo_on_occlum.sh ``` The output will be displayed on the terminal: ``` -5 + 1 = 6 +Cpp FFI test passed! +Multithreading mmap test passed! ``` diff --git a/demos/rust/rust_app/Cargo.toml b/demos/rust/rust_app/Cargo.toml index 7473eaaf..7d0798cb 100644 --- a/demos/rust/rust_app/Cargo.toml +++ b/demos/rust/rust_app/Cargo.toml @@ -6,6 +6,7 @@ build = "build.rs" [dependencies] libc = "0.2" +memmap = "0.7.0" [build-dependencies] cc = "1.0" diff --git a/demos/rust/rust_app/src/main.rs b/demos/rust/rust_app/src/main.rs index c55841cb..4f4f6128 100644 --- a/demos/rust/rust_app/src/main.rs +++ b/demos/rust/rust_app/src/main.rs @@ -1,12 +1,60 @@ -extern crate libc; - -extern "C" { - fn increment_by_one(input: *mut libc::c_int); +fn main() -> Result<(), Box> { + a::test_cpp_ffi(); + b::test_multithread_mmap() } -fn main() { - let mut input = 5; - let old = input; - unsafe { increment_by_one(&mut input) }; - println!("{} + 1 = {}", old, input); +mod a { + extern crate libc; + + extern "C" { + fn increment_by_one(input: *mut libc::c_int); + } + + pub fn test_cpp_ffi() { + let mut input = 5; + let old = input; + unsafe { increment_by_one(&mut input) }; + assert_eq!(old + 1, input); + println!("Cpp FFI test passed!"); + } +} + +mod b { + use std::fs::File; + use std::io::prelude::*; + use std::io::{Cursor, Read}; + use std::thread::{self, JoinHandle}; + + pub fn test_multithread_mmap() -> Result<(), Box> { + let mut file = File::create("/tmp/file.txt")?; + writeln!( + file, + "e785a7d529d589f13e610548b54ac636e30ff4c4e4d834b903b460" + )?; + + for _ in 0..1000 { + // several thread reads same file + let handlers = (1..4) + .map(|_| { + thread::spawn(|| -> Result<_, std::io::Error> { + let file = File::open("/tmp/file.txt").unwrap(); + let mmap = unsafe { memmap::Mmap::map(&file).unwrap() }; + let mut cursor = Cursor::new(mmap.as_ref()); + let mut buffer: [u8; 6] = [0; 6]; + cursor.read_exact(&mut buffer)?; + Ok(buffer) + }) + }) + .collect::>>>(); + + for handler in handlers { + match handler.join().unwrap() { + Ok(data) => assert_eq!(b"e785a7", &data), + Err(e) => panic!("Error: {:?}", e), + } + } + } + println!("Multithreading mmap test passed!"); + Ok(()) + } }