Skip to content

Instantly share code, notes, and snippets.

@bachue
Created December 21, 2019 04:17
Show Gist options
  • Save bachue/bb084162063e061eeed66b17550f66b3 to your computer and use it in GitHub Desktop.
Save bachue/bb084162063e061eeed66b17550f66b3 to your computer and use it in GitHub Desktop.
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");
}
[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"
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