Allow page fault handler to bypass process lock and fix thread pool wakeup for exited process

toolchain_update
Jiajie Chen 6 years ago
parent 9f03bfc849
commit 0edfc07939

@ -190,7 +190,14 @@ impl ThreadPool {
} }
pub fn wakeup(&self, tid: Tid) { pub fn wakeup(&self, tid: Tid) {
self.set_status(tid, Status::Ready); let mut proc_lock = self.threads[tid].lock();
if let Some(mut proc) = proc_lock.as_mut() {
trace!("thread {} {:?} -> {:?}", tid, proc.status, status);
if let Status::Sleeping = proc.status {
proc.status = Status::Ready;
self.scheduler.push(tid);
}
}
} }
pub fn exit(&self, tid: Tid, code: ExitCode) { pub fn exit(&self, tid: Tid, code: ExitCode) {

@ -1,5 +1,4 @@
use once::*; use once::*;
use crate::arch::interrupt::{consts, enable_irq};
pub mod vga; pub mod vga;
pub mod serial; pub mod serial;

@ -1,6 +1,5 @@
//! Driver for x86 CMOS RTC clock //! Driver for x86 CMOS RTC clock
use crate::arch::interrupt; use crate::arch::interrupt;
use log::*;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
const CMOS_ADDR: u16 = 0x70; const CMOS_ADDR: u16 = 0x70;

@ -11,19 +11,16 @@ use rcore_memory::paging::PageTable;
use rcore_memory::PAGE_SIZE; use rcore_memory::PAGE_SIZE;
use smoltcp::iface::*; use smoltcp::iface::*;
use smoltcp::phy::{self, Checksum, DeviceCapabilities}; use smoltcp::phy::{self, Checksum, DeviceCapabilities};
use smoltcp::socket::*;
use smoltcp::time::Instant; use smoltcp::time::Instant;
use smoltcp::wire::EthernetAddress; use smoltcp::wire::EthernetAddress;
use smoltcp::wire::*; use smoltcp::wire::*;
use smoltcp::Result; use smoltcp::Result;
use volatile::Volatile;
use crate::memory::active_table; use crate::memory::active_table;
use crate::net::SOCKETS; use crate::net::SOCKETS;
use crate::sync::FlagsGuard; use crate::sync::FlagsGuard;
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
use crate::sync::{MutexGuard, SpinNoIrq}; use crate::sync::{MutexGuard, SpinNoIrq};
use crate::HEAP_ALLOCATOR;
use super::super::{provider::Provider, DeviceType, Driver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY}; use super::super::{provider::Provider, DeviceType, Driver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY};

@ -12,7 +12,6 @@ use log::*;
use rcore_memory::paging::PageTable; use rcore_memory::paging::PageTable;
use rcore_memory::PAGE_SIZE; use rcore_memory::PAGE_SIZE;
use smoltcp::phy::{self, DeviceCapabilities}; use smoltcp::phy::{self, DeviceCapabilities};
use smoltcp::socket::SocketSet;
use smoltcp::time::Instant; use smoltcp::time::Instant;
use smoltcp::wire::{EthernetAddress, Ipv4Address}; use smoltcp::wire::{EthernetAddress, Ipv4Address};
use smoltcp::Result; use smoltcp::Result;
@ -20,7 +19,6 @@ use volatile::{ReadOnly, Volatile};
use crate::memory::active_table; use crate::memory::active_table;
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
use crate::sync::{MutexGuard, SpinNoIrq};
use crate::HEAP_ALLOCATOR; use crate::HEAP_ALLOCATOR;
use super::super::bus::virtio_mmio::*; use super::super::bus::virtio_mmio::*;

@ -4,7 +4,7 @@ use crate::consts::MEMORY_OFFSET;
use super::HEAP_ALLOCATOR; use super::HEAP_ALLOCATOR;
use rcore_memory::*; use rcore_memory::*;
pub use rcore_memory::memory_set::{MemoryArea, MemoryAttr, handler::*}; pub use rcore_memory::memory_set::{MemoryArea, MemoryAttr, handler::*};
use crate::process::{process}; use crate::process::process_unsafe;
use crate::sync::SpinNoIrqLock; use crate::sync::SpinNoIrqLock;
use lazy_static::*; use lazy_static::*;
use log::*; use log::*;
@ -102,7 +102,11 @@ impl Drop for KernelStack {
#[cfg(not(feature = "no_mmu"))] #[cfg(not(feature = "no_mmu"))]
pub fn handle_page_fault(addr: usize) -> bool { pub fn handle_page_fault(addr: usize) -> bool {
debug!("page fault @ {:#x}", addr); debug!("page fault @ {:#x}", addr);
process().vm.handle_page_fault(addr)
// This is safe as long as page fault never happens in page fault handler
unsafe {
process_unsafe().vm.handle_page_fault(addr)
}
} }
pub fn init_heap() { pub fn init_heap() {

@ -1,9 +1,6 @@
use alloc::sync::Arc; use alloc::sync::Arc;
use core::fmt;
use crate::arch::rand; use crate::arch::rand;
use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY};
use crate::process::structs::Process;
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
use crate::syscall::*; use crate::syscall::*;

@ -1,4 +1,3 @@
use crate::drivers::Driver;
use crate::drivers::NET_DRIVERS; use crate::drivers::NET_DRIVERS;
use crate::net::SOCKETS; use crate::net::SOCKETS;
use crate::thread; use crate::thread;

@ -32,6 +32,14 @@ pub fn process() -> MutexGuard<'static, Process> {
current_thread().proc.lock() current_thread().proc.lock()
} }
/// Get current process, ignoring its lock
/// Only use this when necessary
pub unsafe fn process_unsafe() -> MutexGuard<'static, Process> {
let thread = current_thread();
thread.proc.force_unlock();
thread.proc.lock()
}
/// Get current thread /// Get current thread
/// ///
/// FIXME: It's obviously unsafe to get &mut ! /// FIXME: It's obviously unsafe to get &mut !

@ -6,7 +6,6 @@ use spin::{Mutex, RwLock};
use xmas_elf::{ElfFile, header, program::{Flags, Type}}; use xmas_elf::{ElfFile, header, program::{Flags, Type}};
use rcore_memory::PAGE_SIZE; use rcore_memory::PAGE_SIZE;
use rcore_thread::Tid; use rcore_thread::Tid;
use rcore_fs::vfs::FileType;
use core::str; use core::str;
use crate::arch::interrupt::{Context, TrapFrame}; use crate::arch::interrupt::{Context, TrapFrame};

@ -66,7 +66,8 @@ pub fn sys_mmap(
let file = proc.get_file(fd)?; let file = proc.get_file(fd)?;
let read_len = file.read_at(offset, data)?; let read_len = file.read_at(offset, data)?;
if read_len != data.len() { if read_len != data.len() {
data[read_len..].iter_mut().map(|x| *x = 0); // use count() to consume the iterator
data[read_len..].iter_mut().map(|x| *x = 0).count();
} }
return Ok(addr); return Ok(addr);
} }

@ -184,6 +184,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
warn!("mount is unimplemented"); warn!("mount is unimplemented");
Err(SysError::EACCES) Err(SysError::EACCES)
} }
SYS_UMOUNT2 => {
warn!("umount2 is unimplemented");
Err(SysError::EACCES)
}
SYS_REBOOT => sys_reboot(args[0] as u32, args[1] as u32, args[2] as u32, args[3] as *const u8), SYS_REBOOT => sys_reboot(args[0] as u32, args[1] as u32, args[2] as u32, args[3] as *const u8),
SYS_GETTID => sys_gettid(), SYS_GETTID => sys_gettid(),
SYS_FUTEX => sys_futex(args[0], args[1] as u32, args[2] as i32, args[3] as *const TimeSpec), SYS_FUTEX => sys_futex(args[0], args[1] as u32, args[2] as i32, args[3] as *const TimeSpec),

Loading…
Cancel
Save