mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-23 09:56:24 +04:00
Added condvar examples.
This commit is contained in:
parent
d6362da0ac
commit
3d658ef199
@ -10,6 +10,7 @@ edition = "2018"
|
|||||||
buddy_system_allocator = "0.6"
|
buddy_system_allocator = "0.6"
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
|
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
|
||||||
|
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
72
user/src/bin/barrier_condvar.rs
Normal file
72
user/src/bin/barrier_condvar.rs
Normal file
@ -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
user/src/bin/barrier_fail.rs
Normal file
33
user/src/bin/barrier_fail.rs
Normal file
@ -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
|
||||||
|
}
|
@ -38,6 +38,8 @@ static SUCC_TESTS: &[(&str, &str, &str, &str, i32)] = &[
|
|||||||
("threads_arg\0", "\0", "\0", "\0", 0),
|
("threads_arg\0", "\0", "\0", "\0", 0),
|
||||||
("threads\0", "\0", "\0", "\0", 0),
|
("threads\0", "\0", "\0", "\0", 0),
|
||||||
("yield\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)] = &[
|
static FAIL_TESTS: &[(&str, &str, &str, &str, i32)] = &[
|
||||||
|
Loading…
Reference in New Issue
Block a user