Skip to content

Commit

Permalink
[WIP] on test apps for axsync, deadlock in barrier?
Browse files Browse the repository at this point in the history
  • Loading branch information
hky1999 committed Oct 29, 2024
1 parent 19eed21 commit 42521b8
Show file tree
Hide file tree
Showing 14 changed files with 682 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ members = [
"rust/task/irq",
"rust/task/affinity",
"rust/task/wait_queue",
"rust/task/sync",
]
exclude = [".arceos"]

Expand Down
15 changes: 15 additions & 0 deletions rust/task/sync/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "arceos-sync"
version = "0.1.0"
edition = "2021"
authors = ["Keyang Hu <[email protected]>"]
description = "A simple demo to test the task synchronization mechanisms provided by ArceOS"

[features]
sched_rr = ["axstd?/sched_rr"]
sched_cfs = ["axstd?/sched_cfs"]

[dependencies]
axstd = { workspace = true, features = ["alloc", "multitask", "irq"], optional = true }

rand = { version = "0.8", default-features = false, features = ["small_rng"] }
32 changes: 32 additions & 0 deletions rust/task/sync/expect_info_smp1_fifo.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
smp = 1
build_mode = release
log_level = info

Primary CPU 0 started,
Found physcial memory regions:
.text (READ | EXECUTE | RESERVED)
.rodata (READ | RESERVED)
.data .tdata .tbss .percpu (READ | WRITE | RESERVED)
.percpu (READ | WRITE | RESERVED)
boot stack (READ | WRITE | RESERVED)
.bss (READ | WRITE | RESERVED)
free memory (READ | WRITE | FREE)
Initialize global memory allocator...
Initialize platform devices...
Initialize scheduling...
use FIFO scheduler.
Initialize interrupt handlers...
Primary CPU 0 init OK.
Hello, synchronization mechanisms test for ArceOS!
Mutex test...
Mutex test ok
Condvar test...
Condvar test ok
Barrier test...
Barrier test OK
RwLock test...
RwLock test ok
Semaphore test...
Semaphore test ok
All synchronization mechanisms provided by ArceOS seem to work fine, enjoy!
Shutting down...
38 changes: 38 additions & 0 deletions rust/task/sync/expect_info_smp4_cfs.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
smp = 4
build_mode = release
log_level = info

CPU 0 started
Found physcial memory regions:
.text (READ | EXECUTE | RESERVED)
.rodata (READ | RESERVED)
.data .tdata .tbss .percpu (READ | WRITE | RESERVED)
.percpu (READ | WRITE | RESERVED)
boot stack (READ | WRITE | RESERVED)
.bss (READ | WRITE | RESERVED)
free memory (READ | WRITE | FREE)
Initialize global memory allocator...
Initialize platform devices...
Initialize scheduling...
use Completely Fair scheduler.
Initialize interrupt handlers...
CPU 0 init OK
CPU 1 started
CPU 2 started
CPU 3 started
CPU 1 init OK
CPU 2 init OK
CPU 3 init OK
Hello, synchronization mechanisms test for ArceOS!
Mutex test...
Mutex test ok
Condvar test...
Condvar test ok
Barrier test...
Barrier test OK
RwLock test...
RwLock test ok
Semaphore test...
Semaphore test ok
All synchronization mechanisms provided by ArceOS seem to work fine, enjoy!
Shutting down...
38 changes: 38 additions & 0 deletions rust/task/sync/expect_info_smp4_fifo.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
smp = 4
build_mode = release
log_level = info

CPU 0 started
Found physcial memory regions:
.text (READ | EXECUTE | RESERVED)
.rodata (READ | RESERVED)
.data .tdata .tbss .percpu (READ | WRITE | RESERVED)
.percpu (READ | WRITE | RESERVED)
boot stack (READ | WRITE | RESERVED)
.bss (READ | WRITE | RESERVED)
free memory (READ | WRITE | FREE)
Initialize global memory allocator...
Initialize platform devices...
Initialize scheduling...
use FIFO scheduler.
Initialize interrupt handlers...
CPU 0 init OK
CPU 1 started
CPU 2 started
CPU 3 started
CPU 1 init OK
CPU 2 init OK
CPU 3 init OK
Hello, synchronization mechanisms test for ArceOS!
Mutex test...
Mutex test ok
Condvar test...
Condvar test ok
Barrier test...
Barrier test OK
RwLock test...
RwLock test ok
Semaphore test...
Semaphore test ok
All synchronization mechanisms provided by ArceOS seem to work fine, enjoy!
Shutting down...
38 changes: 38 additions & 0 deletions rust/task/sync/expect_info_smp4_rr.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
smp = 4
build_mode = release
log_level = info

CPU 0 started
Found physcial memory regions:
.text (READ | EXECUTE | RESERVED)
.rodata (READ | RESERVED)
.data .tdata .tbss .percpu (READ | WRITE | RESERVED)
.percpu (READ | WRITE | RESERVED)
boot stack (READ | WRITE | RESERVED)
.bss (READ | WRITE | RESERVED)
free memory (READ | WRITE | FREE)
Initialize global memory allocator...
Initialize platform devices...
Initialize scheduling...
use Round-robin scheduler.
Initialize interrupt handlers...
CPU 0 init OK
CPU 1 started
CPU 2 started
CPU 3 started
CPU 1 init OK
CPU 2 init OK
CPU 3 init OK
Hello, synchronization mechanisms test for ArceOS!
Mutex test...
Mutex test ok
Condvar test...
Condvar test ok
Barrier test...
Barrier test OK
RwLock test...
RwLock test ok
Semaphore test...
Semaphore test ok
All synchronization mechanisms provided by ArceOS seem to work fine, enjoy!
Shutting down...
76 changes: 76 additions & 0 deletions rust/task/sync/src/barrier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::{Arc, Barrier};
use std::thread;
use std::vec::Vec;

const NUM_TASKS: u32 = 10;
const NUM_ITERS: u32 = 100;

fn test_barrier_rendezvous() {
static BARRIER: Barrier = Barrier::new(NUM_TASKS as usize);

let mut join_handlers = Vec::new();

fn rendezvous() {
for _ in 0..NUM_ITERS {
BARRIER.wait();
}
}

for _ in 0..NUM_TASKS {
join_handlers.push(thread::spawn(rendezvous));
}

// Wait for all threads to finish.
for join_handler in join_handlers {
join_handler.join().unwrap();
}
}

fn test_wait_result() {
static LEADER_FOUND: AtomicBool = AtomicBool::new(false);
static FINISHED_TASKS: AtomicUsize = AtomicUsize::new(0);

let barrier = Arc::new(Barrier::new(NUM_TASKS as _));

let mut join_handlers = Vec::new();

for _ in 0..NUM_TASKS - 1 {
let c = barrier.clone();
join_handlers.push(thread::spawn(move || {
let is_leader = c.wait().is_leader();
if is_leader {
LEADER_FOUND.store(true, Ordering::SeqCst);
}
FINISHED_TASKS.fetch_add(1, Ordering::SeqCst);
}));
}

// At this point, all spawned threads should be blocked,
// so we shouldn't get a true value from `LEADER_FOUND`.
assert!(!LEADER_FOUND.load(Ordering::Acquire));

let leader_found = barrier.wait().is_leader();
if leader_found {
LEADER_FOUND.store(true, Ordering::SeqCst);
}

// Wait for all threads to finish.
for join_handler in join_handlers {
join_handler.join().unwrap();
}

assert_eq!(
FINISHED_TASKS.load(Ordering::Relaxed),
NUM_TASKS as usize - 1
);
// Now, the barrier is cleared and we should get true from `LEADER_FOUND`.
assert!(LEADER_FOUND.load(Ordering::Relaxed));
}

pub fn test_barrier() {
println!("Barrier test...");
thread::spawn(|| test_barrier_rendezvous()).join().unwrap();
thread::spawn(|| test_wait_result()).join().unwrap();
println!("Barrier test OK");
}
Loading

0 comments on commit 42521b8

Please sign in to comment.