blob: fbd02d4dd42dc7cb3a208d83f0dbc3dbcc9beae1 [file] [log] [blame]
#![cfg(feature = "invocation")]
use std::{
sync::{Arc, Barrier},
thread::spawn,
};
use jni::{sys::jint, Executor};
mod util;
use util::{jvm, AtomicIntegerProxy};
#[test]
fn single_thread() {
let executor = Executor::new(jvm().clone());
test_single_thread(executor);
}
#[test]
fn serialized_threads() {
let executor = Executor::new(jvm().clone());
test_serialized_threads(executor);
}
#[test]
fn concurrent_threads() {
let executor = Executor::new(jvm().clone());
const THREAD_NUM: usize = 8;
test_concurrent_threads(executor, THREAD_NUM)
}
fn test_single_thread(executor: Executor) {
let mut atomic = AtomicIntegerProxy::new(executor, 0).unwrap();
assert_eq!(0, atomic.get().unwrap());
assert_eq!(1, atomic.increment_and_get().unwrap());
assert_eq!(3, atomic.add_and_get(2).unwrap());
assert_eq!(3, atomic.get().unwrap());
}
fn test_serialized_threads(executor: Executor) {
let mut atomic = AtomicIntegerProxy::new(executor, 0).unwrap();
assert_eq!(0, atomic.get().unwrap());
let jh = spawn(move || {
assert_eq!(1, atomic.increment_and_get().unwrap());
assert_eq!(3, atomic.add_and_get(2).unwrap());
atomic
});
let mut atomic = jh.join().unwrap();
assert_eq!(3, atomic.get().unwrap());
}
fn test_concurrent_threads(executor: Executor, thread_num: usize) {
const ITERS_PER_THREAD: usize = 10_000;
let mut atomic = AtomicIntegerProxy::new(executor, 0).unwrap();
let barrier = Arc::new(Barrier::new(thread_num));
let mut threads = Vec::new();
for _ in 0..thread_num {
let barrier = Arc::clone(&barrier);
let mut atomic = atomic.clone();
let jh = spawn(move || {
barrier.wait();
for _ in 0..ITERS_PER_THREAD {
atomic.increment_and_get().unwrap();
}
});
threads.push(jh);
}
for jh in threads {
jh.join().unwrap();
}
let expected = (ITERS_PER_THREAD * thread_num) as jint;
assert_eq!(expected, atomic.get().unwrap());
}