cargo fmt

This commit is contained in:
Yifan Wu 2023-03-30 23:01:12 +08:00
parent 214898ccfd
commit 36b1d763f1
32 changed files with 525 additions and 487 deletions

View File

@ -75,7 +75,7 @@ impl FrameAllocator for StackFrameAllocator {
None
} else {
self.current += pages;
let arr:Vec<usize> = (1..pages + 1).collect();
let arr: Vec<usize> = (1..pages + 1).collect();
let v = arr.iter().map(|x| (self.current - x).into()).collect();
Some(v)
}
@ -144,7 +144,6 @@ pub fn frame_allocator_test() {
println!("frame_allocator_test passed!");
}
#[allow(unused)]
pub fn frame_allocator_alloc_more_test() {
let mut v: Vec<FrameTracker> = Vec::new();

View File

@ -1,7 +1,7 @@
pub mod port_table;
pub mod socket;
pub mod tcp;
pub mod udp;
pub mod port_table;
pub use lose_net_stack::IPv4;
@ -95,7 +95,7 @@ pub fn net_interrupt_handler() {
if let Some(socket_index) = get_socket(target, lport, rport) {
push_data(socket_index, tcp_packet.data.to_vec());
set_s_a_by_index(socket_index, tcp_packet.seq, tcp_packet.ack);
}
}
}
_ => {}
}

View File

@ -1,4 +1,4 @@
use alloc::{vec::Vec, sync::Arc};
use alloc::{sync::Arc, vec::Vec};
use lazy_static::lazy_static;
use lose_net_stack::packets::tcp::TCPPacket;
@ -11,7 +11,7 @@ use super::tcp::TCP;
pub struct Port {
pub port: u16,
pub receivable: bool,
pub schedule: Option<Arc<TaskControlBlock>>
pub schedule: Option<Arc<TaskControlBlock>>,
}
lazy_static! {
@ -32,7 +32,7 @@ pub fn listen(port: u16) -> Option<usize> {
let listen_port = Port {
port,
receivable: false,
schedule: None
schedule: None,
};
if index == usize::MAX {
@ -66,10 +66,13 @@ pub fn port_acceptable(listen_index: usize) -> bool {
// check whether it can accept request
pub fn check_accept(port: u16, tcp_packet: &TCPPacket) -> Option<()> {
LISTEN_TABLE.exclusive_session(|listen_table| {
let mut listen_ports: Vec<&mut Option<Port>> = listen_table.iter_mut().filter(|x| match x {
Some(t) => t.port == port && t.receivable == true,
None => false,
}).collect();
let mut listen_ports: Vec<&mut Option<Port>> = listen_table
.iter_mut()
.filter(|x| match x {
Some(t) => t.port == port && t.receivable == true,
None => false,
})
.collect();
if listen_ports.len() == 0 {
None
} else {
@ -90,7 +93,13 @@ pub fn accept_connection(_port: u16, tcp_packet: &TCPPacket, task: Arc<TaskContr
let mut inner = process.inner_exclusive_access();
let fd = inner.alloc_fd();
let tcp_socket = TCP::new(tcp_packet.source_ip, tcp_packet.dest_port, tcp_packet.source_port, tcp_packet.seq, tcp_packet.ack);
let tcp_socket = TCP::new(
tcp_packet.source_ip,
tcp_packet.dest_port,
tcp_packet.source_port,
tcp_packet.seq,
tcp_packet.ack,
);
inner.fd_table[fd] = Some(Arc::new(tcp_socket));
@ -130,4 +139,3 @@ impl File for PortFd {
0
}
}

View File

@ -12,7 +12,7 @@ pub struct Socket {
pub rport: u16, // rempote port
pub buffers: VecDeque<Vec<u8>>, // datas
pub seq: u32,
pub ack: u32
pub ack: u32,
}
lazy_static! {
@ -26,11 +26,9 @@ pub fn get_s_a_by_index(index: usize) -> Option<(u32, u32)> {
assert!(index < socket_table.len());
socket_table.get(index).map_or(None, |x| {
match x {
Some(x) => Some((x.seq, x.ack)),
None => None,
}
socket_table.get(index).map_or(None, |x| match x {
Some(x) => Some((x.seq, x.ack)),
None => None,
})
}
@ -40,9 +38,7 @@ pub fn set_s_a_by_index(index: usize, seq: u32, ack: u32) {
assert!(socket_table.len() > index);
assert!(socket_table[index].is_some());
let sock = socket_table[index]
.as_mut()
.unwrap();
let sock = socket_table[index].as_mut().unwrap();
sock.ack = ack;
sock.seq = seq;
@ -84,7 +80,7 @@ pub fn add_socket(raddr: IPv4, lport: u16, rport: u16) -> Option<usize> {
rport,
buffers: VecDeque::new(),
seq: 0,
ack: 0
ack: 0,
};
if index == usize::MAX {

View File

@ -1,8 +1,8 @@
use alloc::vec;
use lose_net_stack::MacAddress;
use lose_net_stack::IPv4;
use lose_net_stack::TcpFlags;
use lose_net_stack::packets::tcp::TCPPacket;
use lose_net_stack::IPv4;
use lose_net_stack::MacAddress;
use lose_net_stack::TcpFlags;
use crate::{drivers::NET_DEVICE, fs::File};

View File

@ -1,6 +1,6 @@
use crate::sync::{Mutex, UPIntrFreeCell};
use crate::task::{
wakeup_task, block_current_and_run_next, block_current_task, current_task, TaskContext,
block_current_and_run_next, block_current_task, current_task, wakeup_task, TaskContext,
TaskControlBlock,
};
use alloc::{collections::VecDeque, sync::Arc};

View File

@ -1,7 +1,7 @@
use super::UPIntrFreeCell;
use crate::task::TaskControlBlock;
use crate::task::{wakeup_task, current_task};
use crate::task::{block_current_and_run_next, suspend_current_and_run_next};
use crate::task::{current_task, wakeup_task};
use alloc::{collections::VecDeque, sync::Arc};
pub trait Mutex: Sync + Send {

View File

@ -1,5 +1,5 @@
use crate::sync::UPIntrFreeCell;
use crate::task::{wakeup_task, block_current_and_run_next, current_task, TaskControlBlock};
use crate::task::{block_current_and_run_next, current_task, wakeup_task, TaskControlBlock};
use alloc::{collections::VecDeque, sync::Arc};
pub struct Semaphore {

View File

@ -1,6 +1,6 @@
use crate::net::port_table::{listen, PortFd, accept, port_acceptable};
use crate::net::port_table::{accept, listen, port_acceptable, PortFd};
use crate::net::udp::UDP;
use crate::net::{IPv4, net_interrupt_handler};
use crate::net::{net_interrupt_handler, IPv4};
use crate::task::{current_process, current_task, current_trap_cx};
use alloc::sync::Arc;
@ -34,11 +34,11 @@ pub fn sys_listen(port: u16) -> isize {
// accept a tcp connection
pub fn sys_accept(port_index: usize) -> isize {
println!("accepting port {}", port_index);
let task = current_task().unwrap();
accept(port_index, task);
// block_current_and_run_next();
// NOTICE: There does not have interrupt handler, just call it munually.
loop {
net_interrupt_handler();

View File

@ -19,7 +19,7 @@ use switch::__switch;
pub use context::TaskContext;
pub use id::{kstack_alloc, pid_alloc, KernelStack, PidHandle, IDLE_PID};
pub use manager::{add_task, wakeup_task, pid2process, remove_from_pid2process};
pub use manager::{add_task, pid2process, remove_from_pid2process, wakeup_task};
pub use processor::{
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
current_user_token, run_tasks, schedule, take_current_task,

View File

@ -40,7 +40,9 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
unsafe {
PER_THREAD = per_thread;
}
let start = get_time();
let mut v = Vec::new();
for _ in 0..thread_count {

View File

@ -26,8 +26,8 @@ unsafe fn critical_section(t: &mut usize) {
fn lock() {
while OCCUPIED
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_err()
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_err()
{
yield_();
}
@ -57,7 +57,9 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
unsafe {
PER_THREAD = per_thread;
}
let start = get_time();
let mut v = Vec::new();
for _ in 0..thread_count {

View File

@ -42,7 +42,9 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
unsafe {
PER_THREAD = per_thread;
}
let start = get_time();
assert_eq!(mutex_blocking_create(), 0);

View File

@ -43,7 +43,9 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
unsafe {
PER_THREAD = per_thread;
}
let start = get_time();
assert_eq!(mutex_create(), 0);

View File

@ -1,90 +1,95 @@
//! It only works on a single CPU!
#![no_std]
#![no_main]
#![feature(core_intrinsics)]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use user_lib::{exit, get_time, thread_create, waittid};
use core::sync::atomic::{compiler_fence, Ordering};
static mut A: usize = 0;
static mut FLAG: [bool; 2] = [false; 2];
static mut TURN: usize = 0;
const PER_THREAD_DEFAULT: usize = 2000;
const THREAD_COUNT_DEFAULT: usize = 2;
static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize;
let cur = a.read_volatile();
for _ in 0..500 {
*t = (*t) * (*t) % 10007;
}
a.write_volatile(cur + 1);
}
unsafe fn lock(id: usize) {
FLAG[id] = true;
let j = 1 - id;
TURN = j;
// Tell the compiler not to reorder memory operations
// across this fence.
compiler_fence(Ordering::SeqCst);
// Why do we need to use volatile_read here?
// Otherwise the compiler will assume that they will never
// be changed on this thread. Thus, they will be accessed
// only once!
while vload!(&FLAG[j]) && vload!(&TURN) == j {}
}
unsafe fn unlock(id: usize) {
FLAG[id] = false;
}
unsafe fn f(id: usize) -> ! {
let mut t = 2usize;
for _iter in 0..PER_THREAD {
lock(id);
critical_section(&mut t);
unlock(id);
}
exit(t as i32)
}
#[no_mangle]
pub fn main(argc: usize, argv: &[&str]) -> i32 {
let mut thread_count = THREAD_COUNT_DEFAULT;
let mut per_thread = PER_THREAD_DEFAULT;
if argc >= 2 {
thread_count = argv[1].parse().unwrap();
if argc >= 3 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
// uncomment this if you want to check the assembly
// println!(
// "addr: lock={:#x}, unlock={:#x}",
// lock as usize,
// unlock as usize
// );
let start = get_time();
let mut v = Vec::new();
assert_eq!(thread_count, 2, "Peterson works when there are only 2 threads.");
for id in 0..thread_count {
v.push(thread_create(f as usize, id) as usize);
}
let mut time_cost = Vec::new();
for tid in v.iter() {
time_cost.push(waittid(*tid));
}
println!("time cost is {}ms", get_time() - start);
assert_eq!(unsafe { A }, unsafe { PER_THREAD } * thread_count);
0
}
//! It only works on a single CPU!
#![no_std]
#![no_main]
#![feature(core_intrinsics)]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use core::sync::atomic::{compiler_fence, Ordering};
use user_lib::{exit, get_time, thread_create, waittid};
static mut A: usize = 0;
static mut FLAG: [bool; 2] = [false; 2];
static mut TURN: usize = 0;
const PER_THREAD_DEFAULT: usize = 2000;
const THREAD_COUNT_DEFAULT: usize = 2;
static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize;
let cur = a.read_volatile();
for _ in 0..500 {
*t = (*t) * (*t) % 10007;
}
a.write_volatile(cur + 1);
}
unsafe fn lock(id: usize) {
FLAG[id] = true;
let j = 1 - id;
TURN = j;
// Tell the compiler not to reorder memory operations
// across this fence.
compiler_fence(Ordering::SeqCst);
// Why do we need to use volatile_read here?
// Otherwise the compiler will assume that they will never
// be changed on this thread. Thus, they will be accessed
// only once!
while vload!(&FLAG[j]) && vload!(&TURN) == j {}
}
unsafe fn unlock(id: usize) {
FLAG[id] = false;
}
unsafe fn f(id: usize) -> ! {
let mut t = 2usize;
for _iter in 0..PER_THREAD {
lock(id);
critical_section(&mut t);
unlock(id);
}
exit(t as i32)
}
#[no_mangle]
pub fn main(argc: usize, argv: &[&str]) -> i32 {
let mut thread_count = THREAD_COUNT_DEFAULT;
let mut per_thread = PER_THREAD_DEFAULT;
if argc >= 2 {
thread_count = argv[1].parse().unwrap();
if argc >= 3 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe {
PER_THREAD = per_thread;
}
// uncomment this if you want to check the assembly
// println!(
// "addr: lock={:#x}, unlock={:#x}",
// lock as usize,
// unlock as usize
// );
let start = get_time();
let mut v = Vec::new();
assert_eq!(
thread_count, 2,
"Peterson works when there are only 2 threads."
);
for id in 0..thread_count {
v.push(thread_create(f as usize, id) as usize);
}
let mut time_cost = Vec::new();
for tid in v.iter() {
time_cost.push(waittid(*tid));
}
println!("time cost is {}ms", get_time() - start);
assert_eq!(unsafe { A }, unsafe { PER_THREAD } * thread_count);
0
}

View File

@ -1,89 +1,94 @@
//! It only works on a single CPU!
#![no_std]
#![no_main]
#![feature(core_intrinsics)]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use user_lib::{exit, get_time, thread_create, waittid, yield_};
use core::sync::atomic::{compiler_fence, Ordering};
static mut A: usize = 0;
static mut FLAG: [bool; 2] = [false; 2];
static mut TURN: usize = 0;
const PER_THREAD_DEFAULT: usize = 2000;
const THREAD_COUNT_DEFAULT: usize = 2;
static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize;
let cur = a.read_volatile();
for _ in 0..500 {
*t = (*t) * (*t) % 10007;
}
a.write_volatile(cur + 1);
}
unsafe fn lock(id: usize) {
FLAG[id] = true;
let j = 1 - id;
TURN = j;
// Tell the compiler not to reorder memory operations
// across this fence.
compiler_fence(Ordering::SeqCst);
while FLAG[j] && TURN == j {
yield_();
}
}
unsafe fn unlock(id: usize) {
FLAG[id] = false;
}
unsafe fn f(id: usize) -> ! {
let mut t = 2usize;
for _iter in 0..PER_THREAD {
lock(id);
critical_section(&mut t);
unlock(id);
}
exit(t as i32)
}
#[no_mangle]
pub fn main(argc: usize, argv: &[&str]) -> i32 {
let mut thread_count = THREAD_COUNT_DEFAULT;
let mut per_thread = PER_THREAD_DEFAULT;
if argc >= 2 {
thread_count = argv[1].parse().unwrap();
if argc >= 3 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
// uncomment this if you want to check the assembly
// println!(
// "addr: lock={:#x}, unlock={:#x}",
// lock as usize,
// unlock as usize
// );
let start = get_time();
let mut v = Vec::new();
assert_eq!(thread_count, 2, "Peterson works when there are only 2 threads.");
for id in 0..thread_count {
v.push(thread_create(f as usize, id) as usize);
}
let mut time_cost = Vec::new();
for tid in v.iter() {
time_cost.push(waittid(*tid));
}
println!("time cost is {}ms", get_time() - start);
assert_eq!(unsafe { A }, unsafe { PER_THREAD } * thread_count);
0
}
//! It only works on a single CPU!
#![no_std]
#![no_main]
#![feature(core_intrinsics)]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use core::sync::atomic::{compiler_fence, Ordering};
use user_lib::{exit, get_time, thread_create, waittid, yield_};
static mut A: usize = 0;
static mut FLAG: [bool; 2] = [false; 2];
static mut TURN: usize = 0;
const PER_THREAD_DEFAULT: usize = 2000;
const THREAD_COUNT_DEFAULT: usize = 2;
static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize;
let cur = a.read_volatile();
for _ in 0..500 {
*t = (*t) * (*t) % 10007;
}
a.write_volatile(cur + 1);
}
unsafe fn lock(id: usize) {
FLAG[id] = true;
let j = 1 - id;
TURN = j;
// Tell the compiler not to reorder memory operations
// across this fence.
compiler_fence(Ordering::SeqCst);
while FLAG[j] && TURN == j {
yield_();
}
}
unsafe fn unlock(id: usize) {
FLAG[id] = false;
}
unsafe fn f(id: usize) -> ! {
let mut t = 2usize;
for _iter in 0..PER_THREAD {
lock(id);
critical_section(&mut t);
unlock(id);
}
exit(t as i32)
}
#[no_mangle]
pub fn main(argc: usize, argv: &[&str]) -> i32 {
let mut thread_count = THREAD_COUNT_DEFAULT;
let mut per_thread = PER_THREAD_DEFAULT;
if argc >= 2 {
thread_count = argv[1].parse().unwrap();
if argc >= 3 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe {
PER_THREAD = per_thread;
}
// uncomment this if you want to check the assembly
// println!(
// "addr: lock={:#x}, unlock={:#x}",
// lock as usize,
// unlock as usize
// );
let start = get_time();
let mut v = Vec::new();
assert_eq!(
thread_count, 2,
"Peterson works when there are only 2 threads."
);
for id in 0..thread_count {
v.push(thread_create(f as usize, id) as usize);
}
let mut time_cost = Vec::new();
for tid in v.iter() {
time_cost.push(waittid(*tid));
}
println!("time cost is {}ms", get_time() - start);
assert_eq!(unsafe { A }, unsafe { PER_THREAD } * thread_count);
0
}

View File

@ -53,7 +53,9 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
unsafe {
PER_THREAD = per_thread;
}
let start = get_time();
let mut v = Vec::new();
for _ in 0..thread_count {

View File

@ -1,70 +1,72 @@
#![no_std]
#![no_main]
#![feature(core_intrinsics)]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use user_lib::{exit, get_time, thread_create, waittid, yield_};
static mut A: usize = 0;
static mut OCCUPIED: bool = false;
const PER_THREAD_DEFAULT: usize = 10000;
const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize;
let cur = a.read_volatile();
for _ in 0..500 {
*t = (*t) * (*t) % 10007;
}
a.write_volatile(cur + 1);
}
unsafe fn lock() {
while OCCUPIED {
yield_();
}
OCCUPIED = true;
}
unsafe fn unlock() {
OCCUPIED = false;
}
unsafe fn f() -> ! {
let mut t = 2usize;
for _ in 0..PER_THREAD {
lock();
critical_section(&mut t);
unlock();
}
exit(t as i32)
}
#[no_mangle]
pub fn main(argc: usize, argv: &[&str]) -> i32 {
let mut thread_count = THREAD_COUNT_DEFAULT;
let mut per_thread = PER_THREAD_DEFAULT;
if argc >= 2 {
thread_count = argv[1].parse().unwrap();
if argc >= 3 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe { PER_THREAD = per_thread; }
let start = get_time();
let mut v = Vec::new();
for _ in 0..thread_count {
v.push(thread_create(f as usize, 0) as usize);
}
for tid in v.into_iter() {
waittid(tid);
}
println!("time cost is {}ms", get_time() - start);
assert_eq!(unsafe { A }, unsafe { PER_THREAD } * thread_count);
0
}
#![no_std]
#![no_main]
#![feature(core_intrinsics)]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use user_lib::{exit, get_time, thread_create, waittid, yield_};
static mut A: usize = 0;
static mut OCCUPIED: bool = false;
const PER_THREAD_DEFAULT: usize = 10000;
const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize;
let cur = a.read_volatile();
for _ in 0..500 {
*t = (*t) * (*t) % 10007;
}
a.write_volatile(cur + 1);
}
unsafe fn lock() {
while OCCUPIED {
yield_();
}
OCCUPIED = true;
}
unsafe fn unlock() {
OCCUPIED = false;
}
unsafe fn f() -> ! {
let mut t = 2usize;
for _ in 0..PER_THREAD {
lock();
critical_section(&mut t);
unlock();
}
exit(t as i32)
}
#[no_mangle]
pub fn main(argc: usize, argv: &[&str]) -> i32 {
let mut thread_count = THREAD_COUNT_DEFAULT;
let mut per_thread = PER_THREAD_DEFAULT;
if argc >= 2 {
thread_count = argv[1].parse().unwrap();
if argc >= 3 {
per_thread = argv[2].parse().unwrap();
}
}
unsafe {
PER_THREAD = per_thread;
}
let start = get_time();
let mut v = Vec::new();
for _ in 0..thread_count {
v.push(thread_create(f as usize, 0) as usize);
}
for tid in v.into_iter() {
waittid(tid);
}
println!("time cost is {}ms", get_time() - start);
assert_eq!(unsafe { A }, unsafe { PER_THREAD } * thread_count);
0
}

View File

@ -1,72 +1,83 @@
#![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 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
}
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use core::cell::UnsafeCell;
use lazy_static::*;
use user_lib::{
condvar_create, condvar_signal, condvar_wait, exit, mutex_create, mutex_lock, mutex_unlock,
thread_create, waittid,
};
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 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
}

View File

@ -1,33 +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
}
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use user_lib::{exit, thread_create, waittid};
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
}

View File

@ -1,64 +1,64 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec;
use user_lib::exit;
use user_lib::{
semaphore_create, semaphore_down, semaphore_up, mutex_blocking_create, mutex_lock, mutex_unlock,
};
use user_lib::{sleep, thread_create, waittid};
static mut A: usize = 0;
const SEM_ID: usize = 0;
const MUTEX_ID: usize = 0;
unsafe fn first() -> ! {
sleep(10);
println!("First work, Change A --> 1 and wakeup Second");
mutex_lock(MUTEX_ID);
A = 1;
semaphore_up(SEM_ID);
mutex_unlock(MUTEX_ID);
exit(0)
}
unsafe fn second() -> ! {
println!("Second want to continue,but need to wait A=1");
loop {
mutex_lock(MUTEX_ID);
if A == 0 {
println!("Second: A is {}", A);
mutex_unlock(MUTEX_ID);
semaphore_down(SEM_ID);
} else {
mutex_unlock(MUTEX_ID);
break;
}
}
println!("A is {}, Second can work now", A);
exit(0)
}
#[no_mangle]
pub fn main() -> i32 {
// create semaphore & mutex
assert_eq!(semaphore_create(0) as usize, SEM_ID);
assert_eq!(mutex_blocking_create() as usize, MUTEX_ID);
// create threads
let threads = vec![
thread_create(first as usize, 0),
thread_create(second as usize, 0),
];
// wait for all threads to complete
for thread in threads.iter() {
waittid(*thread as usize);
}
println!("test_condvar passed!");
0
}
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use alloc::vec;
use user_lib::exit;
use user_lib::{
mutex_blocking_create, mutex_lock, mutex_unlock, semaphore_create, semaphore_down, semaphore_up,
};
use user_lib::{sleep, thread_create, waittid};
static mut A: usize = 0;
const SEM_ID: usize = 0;
const MUTEX_ID: usize = 0;
unsafe fn first() -> ! {
sleep(10);
println!("First work, Change A --> 1 and wakeup Second");
mutex_lock(MUTEX_ID);
A = 1;
semaphore_up(SEM_ID);
mutex_unlock(MUTEX_ID);
exit(0)
}
unsafe fn second() -> ! {
println!("Second want to continue,but need to wait A=1");
loop {
mutex_lock(MUTEX_ID);
if A == 0 {
println!("Second: A is {}", A);
mutex_unlock(MUTEX_ID);
semaphore_down(SEM_ID);
} else {
mutex_unlock(MUTEX_ID);
break;
}
}
println!("A is {}, Second can work now", A);
exit(0)
}
#[no_mangle]
pub fn main() -> i32 {
// create semaphore & mutex
assert_eq!(semaphore_create(0) as usize, SEM_ID);
assert_eq!(mutex_blocking_create() as usize, MUTEX_ID);
// create threads
let threads = vec![
thread_create(first as usize, 0),
thread_create(second as usize, 0),
];
// wait for all threads to complete
for thread in threads.iter() {
waittid(*thread as usize);
}
println!("test_condvar passed!");
0
}

View File

@ -8,7 +8,7 @@ use user_lib::{Display, VIRTGPU_XRES, VIRTGPU_YRES};
use embedded_graphics::pixelcolor::Rgb888;
use embedded_graphics::prelude::{DrawTarget, Drawable, Point, RgbColor, Size};
use embedded_graphics::primitives::{Circle, Primitive, PrimitiveStyle, Rectangle,Triangle};
use embedded_graphics::primitives::{Circle, Primitive, PrimitiveStyle, Rectangle, Triangle};
const INIT_X: i32 = 80;
const INIT_Y: i32 = 400;
@ -35,10 +35,14 @@ impl DrawingBoard {
.into_styled(PrimitiveStyle::with_fill(Rgb888::BLUE))
.draw(&mut self.disp)
.ok();
Triangle::new(self.latest_pos + Point::new(0, 150), self.latest_pos + Point::new(80, 200), self.latest_pos + Point::new(-120, 300))
.into_styled(PrimitiveStyle::with_stroke(Rgb888::GREEN, 10))
.draw(&mut self.disp)
.ok();
Triangle::new(
self.latest_pos + Point::new(0, 150),
self.latest_pos + Point::new(80, 200),
self.latest_pos + Point::new(-120, 300),
)
.into_styled(PrimitiveStyle::with_stroke(Rgb888::GREEN, 10))
.draw(&mut self.disp)
.ok();
}
fn unpaint(&mut self) {
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE))

View File

@ -3,8 +3,8 @@
extern crate user_lib;
use user_lib::{VIRTGPU_XRES, VIRTGPU_YRES, Display};
use embedded_graphics::prelude::Size;
use user_lib::{Display, VIRTGPU_XRES, VIRTGPU_YRES};
#[no_mangle]
pub fn main() -> i32 {

View File

@ -1,11 +1,11 @@
#![no_std]
#![no_main]
extern crate user_lib;
extern crate alloc;
extern crate user_lib;
use user_lib::console::getchar;
use user_lib::{Display, key_pressed, sleep, VIRTGPU_XRES, VIRTGPU_YRES};
use user_lib::{key_pressed, sleep, Display, VIRTGPU_XRES, VIRTGPU_YRES};
use embedded_graphics::pixelcolor::*;
use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size};

View File

@ -113,7 +113,7 @@ pub fn main() -> i32 {
let mut board = DrawingBoard::new();
let _ = board.disp.clear(Rgb888::BLACK).unwrap();
for i in 0..20 {
let c=getchar();
let c = getchar();
if c == LF || c == CR {
break;
}

View File

@ -22,4 +22,4 @@ pub fn main() -> i32 {
}
}
0
}
}

View File

@ -77,4 +77,4 @@ pub fn main() -> i32 {
}
println!("main thread exited.");
0
}
}

View File

@ -13,4 +13,4 @@ pub fn main() -> i32 {
println!("OORandom: Random number 32bit: {}", rng.rand_i32());
println!("OORandom: Random number range: {}", rng.rand_range(1..100));
0
}
}

View File

@ -69,7 +69,7 @@ impl Task {
// we can allocate memory for it later, but it keeps complexity down and lets us focus on more interesting parts
// to do it here. The important part is that once allocated it MUST NOT move in memory.
Task {
id:id,
id: id,
stack: vec![0_u8; DEFAULT_STACK_SIZE],
ctx: TaskContext::default(),
state: State::Available,

View File

@ -10,7 +10,7 @@ extern crate alloc;
// use http://localhost:6201/ to access the http server
use user_lib::{read, write, listen, accept};
use user_lib::{accept, listen, read, write};
// get url from the tcp request list.
fn get_url_from_tcp_request(req: &[u8]) -> String {
@ -35,8 +35,8 @@ fn handle_tcp_client(client_fd: usize) -> bool {
println!("receive {} bytes", len);
hexdump(&buf[..len as usize]);
// verify whether it is a valid HTTP request simply, [0x47,0x45,0x54, 0x20] is GET
if len < 4 || buf[..4] != [0x47,0x45,0x54, 0x20] {
// verify whether it is a valid HTTP request simply, [0x47,0x45,0x54, 0x20] is GET
if len < 4 || buf[..4] != [0x47, 0x45, 0x54, 0x20] {
println!("it's not a valid http request");
return false;
}
@ -136,12 +136,12 @@ pub fn main() -> i32 {
loop {
let client = accept(tcp_fd as usize);
println!("client connected: {}", client);
if client < 1 {
println!("Failed to accept a client on port 80");
return -1;
}
if handle_tcp_client(client as usize) {
break;
}

View File

@ -1,7 +1,7 @@
use super::*;
use embedded_graphics::pixelcolor::Rgb888;
use embedded_graphics::prelude::{RgbColor, Size};
use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions};
use embedded_graphics::pixelcolor::Rgb888;
use virtio_input_decoder::Decoder;
pub use virtio_input_decoder::{DecodeType, Key, KeyType, Mouse};
@ -24,9 +24,8 @@ pub struct Display {
impl Display {
pub fn new(size: Size) -> Self {
let fb_ptr = framebuffer() as *mut u8;
let fb =
unsafe { core::slice::from_raw_parts_mut(fb_ptr, VIRTGPU_LEN as usize) };
Self { size, fb}
let fb = unsafe { core::slice::from_raw_parts_mut(fb_ptr, VIRTGPU_LEN as usize) };
Self { size, fb }
}
pub fn framebuffer(&mut self) -> &mut [u8] {
self.fb
@ -53,9 +52,7 @@ impl DrawTarget for Display {
I: IntoIterator<Item = embedded_graphics::Pixel<Self::Color>>,
{
pixels.into_iter().for_each(|px| {
let idx = (px.0.y * VIRTGPU_XRES as i32 + px.0.x)
as usize
* 4;
let idx = (px.0.y * VIRTGPU_XRES as i32 + px.0.x) as usize * 4;
if idx + 2 >= self.fb.len() {
return;
}
@ -113,6 +110,7 @@ impl InputEvent {
self.event_type as usize,
self.code as usize,
self.value as usize,
).ok()
)
.ok()
}
}
}

View File

@ -79,4 +79,4 @@ pub fn waittid(tid: usize) -> isize {
exit_code => return exit_code,
}
}
}
}