Created
December 21, 2019 04:17
-
-
Save bachue/bb084162063e061eeed66b17550f66b3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use cbindgen::{Config, ItemType, Language}; | |
use std::env; | |
fn main() { | |
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); | |
let mut config: Config = Default::default(); | |
config.documentation = true; | |
config.export.item_types = vec![ | |
ItemType::Constants, | |
ItemType::Globals, | |
ItemType::Enums, | |
ItemType::Structs, | |
ItemType::Unions, | |
ItemType::OpaqueItems, | |
ItemType::Functions, | |
]; | |
config.include_guard = Some("__ABC_H".to_string()); | |
config.language = Language::C; | |
config.cpp_compat = true; | |
cbindgen::generate_with_config(&crate_dir, config) | |
.expect("Unable to generate bindings") | |
.write_to_file("abc.h"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "abc" | |
version = "0.1.0" | |
authors = ["root"] | |
edition = "2018" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[lib] | |
crate-type = ["cdylib"] | |
[dependencies] | |
libc = "0.2.66" | |
[build-dependencies] | |
cbindgen = "0.9.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use libc::size_t; | |
use std::{thread::spawn, sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering::{AcqRel, Relaxed}}}}; | |
#[no_mangle] | |
pub extern "C" fn test_atomic(ok: *mut bool) -> size_t { | |
let counter1 = Arc::new(AtomicUsize::new(0)); | |
let counter2 = Arc::new(AtomicUsize::new(0)); | |
let result = Arc::new(AtomicBool::new(true)); | |
const TIMES: usize = 10000; | |
let mut threads = Vec::with_capacity(10); | |
for _ in 0..threads.capacity() { | |
let counter1 = counter1.clone(); | |
let counter2 = counter2.clone(); | |
let result = result.clone(); | |
threads.push(spawn(move || { | |
for _ in 0..TIMES { | |
let v1 = counter1.fetch_add(1, AcqRel); | |
let v2 = counter2.fetch_add(1, AcqRel); | |
if v1 > v2 { | |
result.store(false, Relaxed); | |
} | |
} | |
})); | |
} | |
for thread in threads { | |
thread.join().unwrap(); | |
} | |
if !ok.is_null() { | |
unsafe { *ok = result.load(Relaxed) }; | |
} | |
counter1.load(Relaxed) + counter2.load(Relaxed) | |
} | |
#[cfg(test)] | |
mod test { | |
use super::*; | |
use std::io::Result; | |
#[test] | |
fn test_atomic_func() -> Result<()> { | |
let mut ok = false; | |
assert_eq!(test_atomic(&mut ok), 200000); | |
assert!(ok); | |
Ok(()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment