Skip to content

Commit

Permalink
Added condvar examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
wyfcyx committed Jan 25, 2023
1 parent 62b796e commit f259b88
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions user/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ edition = "2018"
buddy_system_allocator = "0.6"
bitflags = "1.2.1"
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
embedded-graphics = "0.7.1"
oorandom ="11"
virtio-input-decoder = "0.1.4"
Expand Down
72 changes: 72 additions & 0 deletions user/src/bin/barrier_condvar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#![no_std]
#![no_main]

#[macro_use]
extern crate user_lib;
extern crate alloc;

use user_lib::{thread_create, exit, waittid, mutex_create, mutex_lock, mutex_unlock, condvar_create, condvar_signal, condvar_wait};
use alloc::vec::Vec;
use core::cell::UnsafeCell;
use lazy_static::*;

const THREAD_NUM: usize = 3;

struct Barrier {
mutex_id: usize,
condvar_id: usize,
count: UnsafeCell<usize>,
}

impl Barrier {
pub fn new() -> Self {
Self {
mutex_id: mutex_create() as usize,
condvar_id: condvar_create() as usize,
count: UnsafeCell::new(0),
}
}
pub fn block(&self) {
mutex_lock(self.mutex_id);
let mut count = self.count.get();
// SAFETY: Here, the accesses of the count is in the
// critical section protected by the mutex.
unsafe { *count = *count + 1; }
if unsafe { *count } == THREAD_NUM {
condvar_signal(self.condvar_id);
} else {
condvar_wait(self.condvar_id, self.mutex_id);
condvar_signal(self.condvar_id);
}
mutex_unlock(self.mutex_id);
}
}

unsafe impl Sync for Barrier {}

lazy_static! {
static ref BARRIER_AB: Barrier = Barrier::new();
static ref BARRIER_BC: Barrier = Barrier::new();
}

fn thread_fn() {
for _ in 0..300 { print!("a"); }
BARRIER_AB.block();
for _ in 0..300 { print!("b"); }
BARRIER_BC.block();
for _ in 0..300 { print!("c"); }
exit(0)
}

#[no_mangle]
pub fn main() -> i32 {
let mut v: Vec<isize> = Vec::new();
for _ in 0..THREAD_NUM {
v.push(thread_create(thread_fn as usize, 0));
}
for tid in v.into_iter() {
waittid(tid as usize);
}
println!("\nOK!");
0
}
33 changes: 33 additions & 0 deletions user/src/bin/barrier_fail.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#![no_std]
#![no_main]

#[macro_use]
extern crate user_lib;
extern crate alloc;

use user_lib::{thread_create, exit, waittid};
use alloc::vec::Vec;

const THREAD_NUM: usize = 3;

fn thread_fn() {
for ch in 'a'..='c' {
for _ in 0..300 {
print!("{}", ch);
}
}
exit(0)
}

#[no_mangle]
pub fn main() -> i32 {
let mut v: Vec<isize> = Vec::new();
for _ in 0..THREAD_NUM {
v.push(thread_create(thread_fn as usize, 0));
}
for tid in v.into_iter() {
waittid(tid as usize);
}
println!("\nOK!");
0
}
2 changes: 2 additions & 0 deletions user/src/bin/usertests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ static SUCC_TESTS: &[(&str, &str, &str, &str, i32)] = &[
("threads_arg\0", "\0", "\0", "\0", 0),
("threads\0", "\0", "\0", "\0", 0),
("yield\0", "\0", "\0", "\0", 0),
("barrier_fail\0", "\0", "\0", "\0", 0),
("barrier_condvar\0", "\0", "\0", "\0", 0),
];

static FAIL_TESTS: &[(&str, &str, &str, &str, i32)] = &[
Expand Down

0 comments on commit f259b88

Please sign in to comment.