Skip to content
4 changes: 4 additions & 0 deletions kernel/src/arch/riscv64/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ impl TimeArch for RiscV64TimeArch {
fn cal_expire_cycles(ns: usize) -> usize {
todo!()
}

fn get_cycles_ns() -> usize {
todo!()
}
}
13 changes: 8 additions & 5 deletions kernel/src/arch/x86_64/driver/apic/apic_timer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::cell::RefCell;
use core::sync::atomic::{fence, Ordering};

use crate::arch::driver::tsc::TSCManager;
use crate::arch::interrupt::TrapFrame;
Expand All @@ -12,7 +13,7 @@ use crate::exception::IrqNumber;

use crate::kdebug;
use crate::mm::percpu::PerCpu;
use crate::sched::core::sched_update_jiffies;
use crate::process::ProcessManager;
use crate::smp::core::smp_get_processor_id;
use crate::smp::cpu::ProcessorId;
use crate::time::clocksource::HZ;
Expand Down Expand Up @@ -66,9 +67,10 @@ impl IrqHandler for LocalApicTimerHandler {
struct LocalApicTimerIrqFlowHandler;

impl IrqFlowHandler for LocalApicTimerIrqFlowHandler {
fn handle(&self, _irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) {
LocalApicTimer::handle_irq().ok();
fn handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame) {
LocalApicTimer::handle_irq(trap_frame).ok();
CurrentApic.send_eoi();
fence(Ordering::SeqCst)
}
}

Expand Down Expand Up @@ -274,8 +276,9 @@ impl LocalApicTimer {
return (res.ecx & (1 << 24)) != 0;
}

pub(super) fn handle_irq() -> Result<IrqReturn, SystemError> {
sched_update_jiffies();
pub(super) fn handle_irq(trap_frame: &TrapFrame) -> Result<IrqReturn, SystemError> {
// sched_update_jiffies();
ProcessManager::update_process_times(trap_frame.is_from_user());
return Ok(IrqReturn::Handled);
}
}
Expand Down
5 changes: 5 additions & 0 deletions kernel/src/arch/x86_64/driver/apic/x2apic.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::sync::atomic::{fence, Ordering};

use x86::msr::{
rdmsr, wrmsr, IA32_APIC_BASE, IA32_X2APIC_APICID, IA32_X2APIC_EOI, IA32_X2APIC_SIVR,
IA32_X2APIC_VERSION,
Expand Down Expand Up @@ -62,9 +64,12 @@ impl LocalAPIC for X2Apic {

/// 发送 EOI (End Of Interrupt)
fn send_eoi(&self) {
fence(Ordering::SeqCst);
unsafe {
wrmsr(IA32_X2APIC_EOI, 0);
}

fence(Ordering::SeqCst);
}

/// 获取 x2APIC 版本
Expand Down
8 changes: 3 additions & 5 deletions kernel/src/arch/x86_64/interrupt/handle.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use core::intrinsics::likely;

use crate::{
arch::{
driver::apic::{apic_timer::APIC_TIMER_IRQ_NUM, CurrentApic, LocalAPIC},
sched::sched,
},
arch::driver::apic::{apic_timer::APIC_TIMER_IRQ_NUM, CurrentApic, LocalAPIC},
exception::{irqdesc::irq_desc_manager, softirq::do_softirq, IrqNumber},
new_sched::{SchedMode, __schedule},
process::{
utils::{current_pcb_flags, current_pcb_preempt_count},
ProcessFlags,
Expand Down Expand Up @@ -47,6 +45,6 @@ unsafe extern "C" fn x86_64_do_irq(trap_frame: &mut TrapFrame, vector: u32) {
if (current_pcb_flags().contains(ProcessFlags::NEED_SCHEDULE))
&& vector == APIC_TIMER_IRQ_NUM.data()
{
sched();
__schedule(SchedMode::SM_PREEMPT);
}
}
4 changes: 2 additions & 2 deletions kernel/src/arch/x86_64/interrupt/ipi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,12 @@ impl IrqFlowHandler for X86_64IpiIrqFlowHandler {
}
IPI_NUM_FLUSH_TLB => {
FlushTLBIpiHandler.handle(irq, None, None).ok();
CurrentApic.send_eoi();
}
_ => {
kerror!("Unknown IPI: {}", irq.data());
CurrentApic.send_eoi();
}
}

CurrentApic.send_eoi();
}
}
4 changes: 2 additions & 2 deletions kernel/src/arch/x86_64/ipc/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::{
fpu::FpState,
interrupt::TrapFrame,
process::table::{USER_CS, USER_DS},
sched::sched,
CurrentIrqArch, MMArch,
},
exception::InterruptArch,
Expand All @@ -17,6 +16,7 @@ use crate::{
},
kerror,
mm::MemoryManagementArch,
new_sched::{schedule, SchedMode},
process::ProcessManager,
syscall::{user_access::UserBufferWriter, Syscall},
};
Expand Down Expand Up @@ -715,7 +715,7 @@ fn sig_stop(sig: Signal) {
);
});
drop(guard);
sched();
schedule(SchedMode::SM_NONE);
// TODO 暂停进程
}
/// 信号默认处理函数——继续进程
Expand Down
12 changes: 11 additions & 1 deletion kernel/src/arch/x86_64/process/idle.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
use core::hint::spin_loop;

use crate::{arch::CurrentIrqArch, exception::InterruptArch, kBUG, process::ProcessManager};
use crate::{
arch::CurrentIrqArch,
exception::InterruptArch,
kBUG,
new_sched::{SchedMode, __schedule},
process::{ProcessFlags, ProcessManager},
};

impl ProcessManager {
/// 每个核的idle进程
pub fn arch_idle_func() -> ! {
loop {
let pcb = ProcessManager::current_pcb();
if pcb.flags().contains(ProcessFlags::NEED_SCHEDULE) {
__schedule(SchedMode::SM_NONE);
}
if CurrentIrqArch::is_irq_enabled() {
unsafe {
x86::halt();
Expand Down
35 changes: 35 additions & 0 deletions kernel/src/arch/x86_64/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,8 @@ pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<Str
current_pcb.flags().remove(ProcessFlags::KTHREAD);
current_pcb.worker_private().take();

*current_pcb.sched_info().sched_policy.write_irqsave() = crate::new_sched::SchedPolicy::CFS;

let mut trap_frame = TrapFrame::new();

compiler_fence(Ordering::SeqCst);
Expand Down Expand Up @@ -591,6 +593,7 @@ unsafe extern "sysv64" fn ready_to_switch_to_user(
new_rip: usize,
) -> ! {
*(trapframe_vaddr as *mut TrapFrame) = trap_frame;
compiler_fence(Ordering::SeqCst);
asm!(
"swapgs",
"mov rsp, {trapframe_vaddr}",
Expand All @@ -601,3 +604,35 @@ unsafe extern "sysv64" fn ready_to_switch_to_user(
);
unreachable!()
}

// bitflags! {
// pub struct ProcessThreadFlags: u32 {
// /*
// * thread information flags
// * - these are process state flags that various assembly files
// * may need to access
// */
// const TIF_NOTIFY_RESUME = 1 << 1; /* callback before returning to user */
// const TIF_SIGPENDING = 1 << 2; /* signal pending */
// const TIF_NEED_RESCHED = 1 << 3; /* rescheduling necessary */
// const TIF_SINGLESTEP = 1 << 4; /* reenable singlestep on user return*/
// const TIF_SSBD = 1 << 5; /* Speculative store bypass disable */
// const TIF_SPEC_IB = 1 << 9; /* Indirect branch speculation mitigation */
// const TIF_SPEC_L1D_FLUSH = 1 << 10; /* Flush L1D on mm switches (processes) */
// const TIF_USER_RETURN_NOTIFY = 1 << 11; /* notify kernel of userspace return */
// const TIF_UPROBE = 1 << 12; /* breakpointed or singlestepping */
// const TIF_PATCH_PENDING = 1 << 13; /* pending live patching update */
// const TIF_NEED_FPU_LOAD = 1 << 14; /* load FPU on return to userspace */
// const TIF_NOCPUID = 1 << 15; /* CPUID is not accessible in userland */
// const TIF_NOTSC = 1 << 16; /* TSC is not accessible in userland */
// const TIF_NOTIFY_SIGNAL = 1 << 17; /* signal notifications exist */
// const TIF_MEMDIE = 1 << 20; /* is terminating due to OOM killer */
// const TIF_POLLING_NRFLAG = 1 << 21; /* idle is polling for TIF_NEED_RESCHED */
// const TIF_IO_BITMAP = 1 << 22; /* uses I/O bitmap */
// const TIF_SPEC_FORCE_UPDATE = 1 << 23; /* Force speculation MSR update in context switch */
// const TIF_FORCED_TF = 1 << 24; /* true if TF in eflags artificially */
// const TIF_BLOCKSTEP = 1 << 25; /* set when we want DEBUGCTLMSR_BTF */
// const TIF_LAZY_MMU_UPDATES = 1 << 27; /* task is updating the mmu lazily */
// const TIF_ADDR32 = 1 << 29; /* 32-bit address space on 64 bits */
// }
// }
23 changes: 11 additions & 12 deletions kernel/src/arch/x86_64/sched.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
use core::hint::spin_loop;

use crate::{
exception::InterruptArch, include::bindings::bindings::enter_syscall_int, sched::SchedArch,
smp::core::smp_get_processor_id, syscall::SYS_SCHED,
};
use crate::{exception::InterruptArch, sched::SchedArch, smp::core::smp_get_processor_id};

use super::{driver::apic::apic_timer::apic_timer_init, CurrentIrqArch};

/// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。
/// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。
#[no_mangle]
pub extern "C" fn sched() {
unsafe {
enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0);
}
}
// /// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。
// /// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。
// #[no_mangle]
// pub extern "C" fn sched() {
// let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
// __schedule(SchedMode::SM_NONE);
// // unsafe {
// // enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0);
// // }
// }

static mut BSP_INIT_OK: bool = false;

Expand Down
4 changes: 4 additions & 0 deletions kernel/src/arch/x86_64/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ impl TimeArch for X86_64TimeArch {
fn cal_expire_cycles(ns: usize) -> usize {
Self::get_cycles() + ns * TSCManager::cpu_khz() as usize / 1000000
}

fn get_cycles_ns() -> usize {
Self::get_cycles() * 1000000 / TSCManager::cpu_khz() as usize
}
}
19 changes: 8 additions & 11 deletions kernel/src/driver/tty/kthread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ use alloc::{string::ToString, sync::Arc};
use kdepends::thingbuf::StaticThingBuf;

use crate::{
arch::sched::sched,
arch::CurrentIrqArch,
exception::InterruptArch,
new_sched::{schedule, SchedMode},
process::{
kthread::{KernelThreadClosure, KernelThreadMechanism},
ProcessControlBlock, ProcessFlags,
ProcessControlBlock, ProcessManager,
},
};

Expand All @@ -34,15 +36,9 @@ fn tty_refresh_thread() -> i32 {
loop {
if KEYBUF.is_empty() {
// 如果缓冲区为空,就休眠
unsafe {
TTY_REFRESH_THREAD
.as_ref()
.unwrap()
.flags()
.insert(ProcessFlags::NEED_SCHEDULE)
};

sched();
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
ProcessManager::mark_sleep(true).expect("TTY_REFRESH_THREAD can not mark sleep");
schedule(SchedMode::SM_NONE);
}

let to_dequeue = core::cmp::min(KEYBUF.len(), TO_DEQUEUE_MAX);
Expand All @@ -63,4 +59,5 @@ pub fn send_to_tty_refresh_thread(data: &[u8]) {
for item in data {
KEYBUF.push(*item).ok();
}
let _ = ProcessManager::wakeup(unsafe { TTY_REFRESH_THREAD.as_ref().unwrap() });
}
2 changes: 1 addition & 1 deletion kernel/src/driver/tty/tty_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl TtyCore {

self.core()
.write_wq
.wakeup(EPollEventType::EPOLLOUT.bits() as u64);
.wakeup_any(EPollEventType::EPOLLOUT.bits() as u64);
}

pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
Expand Down
2 changes: 2 additions & 0 deletions kernel/src/driver/tty/tty_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use super::{
tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
tty_job_control::TtyJobCtrlManager,
tty_port::init_tty_port,
virtual_terminal::vty_init,
};

Expand Down Expand Up @@ -493,6 +494,7 @@ pub struct TtyFilePrivateData {
#[unified_init(INITCALL_DEVICE)]
#[inline(never)]
pub fn tty_init() -> Result<(), SystemError> {
init_tty_port();
let tty = TtyDevice::new(
"tty0",
IdTable::new(
Expand Down
7 changes: 4 additions & 3 deletions kernel/src/driver/tty/tty_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use super::{
termios::Termios,
tty_core::{TtyCore, TtyCoreData},
tty_ldisc::TtyLdiscManager,
tty_port::TTY_PORTS,
tty_port::tty_port,
virtual_terminal::virtual_console::CURRENT_VCNUM,
};

Expand Down Expand Up @@ -218,8 +218,9 @@ impl TtyDriver {
let core = tty.core();

if core.port().is_none() {
TTY_PORTS[core.index()].setup_tty(Arc::downgrade(&tty));
tty.set_port(TTY_PORTS[core.index()].clone());
let port = tty_port(core.index());
port.setup_tty(Arc::downgrade(&tty));
tty.set_port(port);
}

TtyLdiscManager::ldisc_setup(tty.clone(), None)?;
Expand Down
30 changes: 19 additions & 11 deletions kernel/src/driver/tty/tty_port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,29 @@ use super::{tty_core::TtyCore, virtual_terminal::virtual_console::CURRENT_VCNUM}

const TTY_PORT_BUFSIZE: usize = 4096;

lazy_static! {
pub static ref TTY_PORTS: Vec<Arc<dyn TtyPort>> = {
let mut v: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(MAX_NR_CONSOLES as usize);
for _ in 0..MAX_NR_CONSOLES as usize {
v.push(Arc::new(DefaultTtyPort::new()))
}

v
};
}
static mut TTY_PORTS: Option<Vec<Arc<dyn TtyPort>>> = None;

/// 获取当前tty port
#[inline]
pub fn current_tty_port() -> Arc<dyn TtyPort> {
TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
let ports = unsafe { TTY_PORTS.as_ref().unwrap() };
ports[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
}

pub fn init_tty_port() {
let mut v: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(MAX_NR_CONSOLES as usize);
for _ in 0..MAX_NR_CONSOLES as usize {
v.push(Arc::new(DefaultTtyPort::new()))
}

unsafe {
TTY_PORTS = Some(v);
}
}

pub fn tty_port(index: usize) -> Arc<dyn TtyPort> {
let ports = unsafe { TTY_PORTS.as_ref().unwrap() };
ports[index].clone()
}

#[allow(dead_code)]
Expand Down
Loading