mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
Patch fix sched (#419)
1.解决waitqueue sleep的时候,由于preempt count不为0,导致sched失败,从而导致该waitqueue下一次wakeup时,会把pcb多次加入调度队列的bug 2.修复socket inode 的read和write方法里面没有使用no_preempt的问题 3. 修复cpu0的内核栈由于脏数据导致new_idle的时候set pcb报错的问题 --------- Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
8058ccb307
commit
2f6f547ae0
@ -88,6 +88,7 @@ impl phy::TxToken for E1000ETxToken {
|
|||||||
let result = f(buffer.as_mut_slice());
|
let result = f(buffer.as_mut_slice());
|
||||||
let mut device = self.driver.inner.lock();
|
let mut device = self.driver.inner.lock();
|
||||||
device.e1000e_transmit(buffer);
|
device.e1000e_transmit(buffer);
|
||||||
|
buffer.free_buffer();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,5 +130,4 @@ pub fn panic(info: &PanicInfo) -> ! {
|
|||||||
|
|
||||||
println!("Current PCB:\n\t{:?}", *(ProcessManager::current_pcb()));
|
println!("Current PCB:\n\t{:?}", *(ProcessManager::current_pcb()));
|
||||||
ProcessManager::exit(usize::MAX);
|
ProcessManager::exit(usize::MAX);
|
||||||
unreachable!();
|
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ pub struct RwLock<T> {
|
|||||||
pub struct RwLockReadGuard<'a, T: 'a> {
|
pub struct RwLockReadGuard<'a, T: 'a> {
|
||||||
data: *const T,
|
data: *const T,
|
||||||
lock: &'a AtomicU32,
|
lock: &'a AtomicU32,
|
||||||
|
irq_guard: Option<IrqFlagsGuard>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief UPGRADED是介于READER和WRITER之间的一种锁,它可以升级为WRITER,
|
/// @brief UPGRADED是介于READER和WRITER之间的一种锁,它可以升级为WRITER,
|
||||||
@ -53,6 +54,7 @@ pub struct RwLockReadGuard<'a, T: 'a> {
|
|||||||
pub struct RwLockUpgradableGuard<'a, T: 'a> {
|
pub struct RwLockUpgradableGuard<'a, T: 'a> {
|
||||||
data: *const T,
|
data: *const T,
|
||||||
inner: &'a RwLock<T>,
|
inner: &'a RwLock<T>,
|
||||||
|
irq_guard: Option<IrqFlagsGuard>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief WRITER守卫的数据结构
|
/// @brief WRITER守卫的数据结构
|
||||||
@ -144,6 +146,7 @@ impl<T> RwLock<T> {
|
|||||||
return Some(RwLockReadGuard {
|
return Some(RwLockReadGuard {
|
||||||
data: unsafe { &*self.data.get() },
|
data: unsafe { &*self.data.get() },
|
||||||
lock: &self.lock,
|
lock: &self.lock,
|
||||||
|
irq_guard: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,6 +163,19 @@ impl<T> RwLock<T> {
|
|||||||
} //忙等待
|
} //忙等待
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_irqsave(&self) -> RwLockReadGuard<T> {
|
||||||
|
loop {
|
||||||
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
|
match self.try_read() {
|
||||||
|
Some(mut guard) => {
|
||||||
|
guard.irq_guard = Some(irq_guard);
|
||||||
|
return guard;
|
||||||
|
}
|
||||||
|
None => spin_loop(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
/// @brief 获取读者+UPGRADER的数量, 不能保证能否获得同步值
|
/// @brief 获取读者+UPGRADER的数量, 不能保证能否获得同步值
|
||||||
@ -256,6 +272,7 @@ impl<T> RwLock<T> {
|
|||||||
return Some(RwLockUpgradableGuard {
|
return Some(RwLockUpgradableGuard {
|
||||||
inner: self,
|
inner: self,
|
||||||
data: unsafe { &mut *self.data.get() },
|
data: unsafe { &mut *self.data.get() },
|
||||||
|
irq_guard: None,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
@ -274,6 +291,21 @@ impl<T> RwLock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// @brief 获得UPGRADER守卫
|
||||||
|
pub fn upgradeable_read_irqsave(&self) -> RwLockUpgradableGuard<T> {
|
||||||
|
loop {
|
||||||
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
|
match self.try_upgradeable_read() {
|
||||||
|
Some(mut guard) => {
|
||||||
|
guard.irq_guard = Some(irq_guard);
|
||||||
|
return guard;
|
||||||
|
}
|
||||||
|
None => spin_loop(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
//extremely unsafe behavior
|
//extremely unsafe behavior
|
||||||
@ -332,7 +364,7 @@ impl<'rwlock, T> RwLockUpgradableGuard<'rwlock, T> {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
/// @brief 尝试将UPGRADER守卫升级为WRITER守卫
|
/// @brief 尝试将UPGRADER守卫升级为WRITER守卫
|
||||||
pub fn try_upgrade(self) -> Result<RwLockWriteGuard<'rwlock, T>, Self> {
|
pub fn try_upgrade(mut self) -> Result<RwLockWriteGuard<'rwlock, T>, Self> {
|
||||||
let res = self.inner.lock.compare_exchange(
|
let res = self.inner.lock.compare_exchange(
|
||||||
UPGRADED,
|
UPGRADED,
|
||||||
WRITER,
|
WRITER,
|
||||||
@ -343,13 +375,13 @@ impl<'rwlock, T> RwLockUpgradableGuard<'rwlock, T> {
|
|||||||
|
|
||||||
if res.is_ok() {
|
if res.is_ok() {
|
||||||
let inner = self.inner;
|
let inner = self.inner;
|
||||||
|
let irq_guard = self.irq_guard.take();
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
|
|
||||||
Ok(RwLockWriteGuard {
|
Ok(RwLockWriteGuard {
|
||||||
data: unsafe { &mut *inner.data.get() },
|
data: unsafe { &mut *inner.data.get() },
|
||||||
inner,
|
inner,
|
||||||
irq_guard: None,
|
irq_guard,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(self)
|
Err(self)
|
||||||
@ -373,19 +405,20 @@ impl<'rwlock, T> RwLockUpgradableGuard<'rwlock, T> {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
/// @brief UPGRADER降级为READER
|
/// @brief UPGRADER降级为READER
|
||||||
pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> {
|
pub fn downgrade(mut self) -> RwLockReadGuard<'rwlock, T> {
|
||||||
while self.inner.current_reader().is_err() {
|
while self.inner.current_reader().is_err() {
|
||||||
spin_loop();
|
spin_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner: &RwLock<T> = self.inner;
|
let inner: &RwLock<T> = self.inner;
|
||||||
|
let irq_guard = self.irq_guard.take();
|
||||||
// 自动移去UPGRADED比特位
|
// 自动移去UPGRADED比特位
|
||||||
mem::drop(self);
|
mem::drop(self);
|
||||||
|
|
||||||
RwLockReadGuard {
|
RwLockReadGuard {
|
||||||
data: unsafe { &*inner.data.get() },
|
data: unsafe { &*inner.data.get() },
|
||||||
lock: &inner.lock,
|
lock: &inner.lock,
|
||||||
|
irq_guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,26 +459,27 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
/// @brief 将WRITER降级为READER
|
/// @brief 将WRITER降级为READER
|
||||||
pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> {
|
pub fn downgrade(mut self) -> RwLockReadGuard<'rwlock, T> {
|
||||||
while self.inner.current_reader().is_err() {
|
while self.inner.current_reader().is_err() {
|
||||||
spin_loop();
|
spin_loop();
|
||||||
}
|
}
|
||||||
//本质上来说绝对保证没有任何读者
|
//本质上来说绝对保证没有任何读者
|
||||||
|
|
||||||
let inner = self.inner;
|
let inner = self.inner;
|
||||||
|
let irq_guard = self.irq_guard.take();
|
||||||
mem::drop(self);
|
mem::drop(self);
|
||||||
|
|
||||||
return RwLockReadGuard {
|
return RwLockReadGuard {
|
||||||
data: unsafe { &*inner.data.get() },
|
data: unsafe { &*inner.data.get() },
|
||||||
lock: &inner.lock,
|
lock: &inner.lock,
|
||||||
|
irq_guard,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
/// @brief 将WRITER降级为UPGRADER
|
/// @brief 将WRITER降级为UPGRADER
|
||||||
pub fn downgrade_to_upgradeable(self) -> RwLockUpgradableGuard<'rwlock, T> {
|
pub fn downgrade_to_upgradeable(mut self) -> RwLockUpgradableGuard<'rwlock, T> {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
self.inner.lock.load(Ordering::Acquire) & (WRITER | UPGRADED),
|
self.inner.lock.load(Ordering::Acquire) & (WRITER | UPGRADED),
|
||||||
WRITER
|
WRITER
|
||||||
@ -455,11 +489,13 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
|
|||||||
|
|
||||||
let inner = self.inner;
|
let inner = self.inner;
|
||||||
|
|
||||||
|
let irq_guard = self.irq_guard.take();
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
|
|
||||||
return RwLockUpgradableGuard {
|
return RwLockUpgradableGuard {
|
||||||
inner,
|
inner,
|
||||||
data: unsafe { &*inner.data.get() },
|
data: unsafe { &*inner.data.get() },
|
||||||
|
irq_guard,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
use core::intrinsics::unlikely;
|
||||||
|
|
||||||
use alloc::{collections::LinkedList, sync::Arc, vec::Vec};
|
use alloc::{collections::LinkedList, sync::Arc, vec::Vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -26,8 +28,20 @@ pub struct WaitQueue(SpinLock<InnerWaitQueue>);
|
|||||||
impl WaitQueue {
|
impl WaitQueue {
|
||||||
pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT));
|
pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT));
|
||||||
|
|
||||||
|
fn before_sleep_check(&self, max_preempt: usize) {
|
||||||
|
let pcb = ProcessManager::current_pcb();
|
||||||
|
if unlikely(pcb.preempt_count() > max_preempt) {
|
||||||
|
kwarn!(
|
||||||
|
"Process {:?}: Try to sleep when preempt count is {}",
|
||||||
|
pcb.pid(),
|
||||||
|
pcb.preempt_count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断
|
/// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断
|
||||||
pub fn sleep(&self) {
|
pub fn sleep(&self) {
|
||||||
|
self.before_sleep_check(0);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
|
||||||
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
||||||
panic!("sleep error: {:?}", e);
|
panic!("sleep error: {:?}", e);
|
||||||
@ -42,6 +56,7 @@ impl WaitQueue {
|
|||||||
where
|
where
|
||||||
F: FnOnce(),
|
F: FnOnce(),
|
||||||
{
|
{
|
||||||
|
self.before_sleep_check(0);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
||||||
@ -50,6 +65,7 @@ impl WaitQueue {
|
|||||||
drop(irq_guard);
|
drop(irq_guard);
|
||||||
guard.wait_list.push_back(ProcessManager::current_pcb());
|
guard.wait_list.push_back(ProcessManager::current_pcb());
|
||||||
f();
|
f();
|
||||||
|
|
||||||
drop(guard);
|
drop(guard);
|
||||||
sched();
|
sched();
|
||||||
}
|
}
|
||||||
@ -69,6 +85,7 @@ impl WaitQueue {
|
|||||||
/// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数,
|
/// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数,
|
||||||
/// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。
|
/// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。
|
||||||
pub unsafe fn sleep_without_schedule(&self) {
|
pub unsafe fn sleep_without_schedule(&self) {
|
||||||
|
self.before_sleep_check(0);
|
||||||
// 安全检查:确保当前处于中断禁止状态
|
// 安全检查:确保当前处于中断禁止状态
|
||||||
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
@ -80,6 +97,7 @@ impl WaitQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn sleep_without_schedule_uninterruptible(&self) {
|
pub unsafe fn sleep_without_schedule_uninterruptible(&self) {
|
||||||
|
self.before_sleep_check(0);
|
||||||
// 安全检查:确保当前处于中断禁止状态
|
// 安全检查:确保当前处于中断禁止状态
|
||||||
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
@ -91,6 +109,7 @@ impl WaitQueue {
|
|||||||
}
|
}
|
||||||
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断
|
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断
|
||||||
pub fn sleep_uninterruptible(&self) {
|
pub fn sleep_uninterruptible(&self) {
|
||||||
|
self.before_sleep_check(0);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
|
||||||
@ -105,6 +124,7 @@ impl WaitQueue {
|
|||||||
/// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
|
/// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
|
||||||
/// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
|
/// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
|
||||||
pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
|
pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
|
||||||
|
self.before_sleep_check(1);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
||||||
@ -120,6 +140,7 @@ impl WaitQueue {
|
|||||||
/// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
|
/// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
|
||||||
/// 在当前进程的pcb加入队列后,解锁指定的Mutex。
|
/// 在当前进程的pcb加入队列后,解锁指定的Mutex。
|
||||||
pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
|
pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
|
||||||
|
self.before_sleep_check(1);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
||||||
@ -135,6 +156,7 @@ impl WaitQueue {
|
|||||||
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
|
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
|
||||||
/// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
|
/// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
|
||||||
pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
|
pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
|
||||||
|
self.before_sleep_check(1);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
|
||||||
@ -150,6 +172,7 @@ impl WaitQueue {
|
|||||||
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
|
/// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
|
||||||
/// 在当前进程的pcb加入队列后,解锁指定的Mutex。
|
/// 在当前进程的pcb加入队列后,解锁指定的Mutex。
|
||||||
pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
|
pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
|
||||||
|
self.before_sleep_check(1);
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
|
||||||
|
@ -1144,6 +1144,10 @@ impl SocketInode {
|
|||||||
pub fn inner(&self) -> SpinLockGuard<Box<dyn Socket>> {
|
pub fn inner(&self) -> SpinLockGuard<Box<dyn Socket>> {
|
||||||
return self.0.lock();
|
return self.0.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn inner_no_preempt(&self) -> SpinLockGuard<Box<dyn Socket>> {
|
||||||
|
return self.0.lock_no_preempt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexNode for SocketInode {
|
impl IndexNode for SocketInode {
|
||||||
@ -1173,7 +1177,7 @@ impl IndexNode for SocketInode {
|
|||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
_data: &mut crate::filesystem::vfs::FilePrivateData,
|
_data: &mut crate::filesystem::vfs::FilePrivateData,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
return self.0.lock().read(&mut buf[0..len]).0;
|
return self.0.lock_no_preempt().read(&mut buf[0..len]).0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_at(
|
fn write_at(
|
||||||
@ -1183,7 +1187,7 @@ impl IndexNode for SocketInode {
|
|||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
_data: &mut crate::filesystem::vfs::FilePrivateData,
|
_data: &mut crate::filesystem::vfs::FilePrivateData,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
return self.0.lock().write(&buf[0..len], None);
|
return self.0.lock_no_preempt().write(&buf[0..len], None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self) -> Result<crate::filesystem::vfs::PollStatus, SystemError> {
|
fn poll(&self) -> Result<crate::filesystem::vfs::PollStatus, SystemError> {
|
||||||
|
@ -173,7 +173,7 @@ impl Syscall {
|
|||||||
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
let mut socket = socket.inner();
|
let mut socket = unsafe { socket.inner_no_preempt() };
|
||||||
// kdebug!("connect to {:?}...", endpoint);
|
// kdebug!("connect to {:?}...", endpoint);
|
||||||
socket.connect(endpoint)?;
|
socket.connect(endpoint)?;
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
@ -191,7 +191,7 @@ impl Syscall {
|
|||||||
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
let mut socket = socket.inner();
|
let mut socket = unsafe { socket.inner_no_preempt() };
|
||||||
socket.bind(endpoint)?;
|
socket.bind(endpoint)?;
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ impl Syscall {
|
|||||||
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
let socket = socket.inner();
|
let socket = unsafe { socket.inner_no_preempt() };
|
||||||
return socket.write(buf, endpoint);
|
return socket.write(buf, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ impl Syscall {
|
|||||||
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
let socket = socket.inner();
|
let socket = unsafe { socket.inner_no_preempt() };
|
||||||
|
|
||||||
let (n, endpoint) = socket.read(buf);
|
let (n, endpoint) = socket.read(buf);
|
||||||
drop(socket);
|
drop(socket);
|
||||||
@ -275,7 +275,7 @@ impl Syscall {
|
|||||||
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
let socket = socket.inner();
|
let socket = unsafe { socket.inner_no_preempt() };
|
||||||
|
|
||||||
let mut buf = iovs.new_buf(true);
|
let mut buf = iovs.new_buf(true);
|
||||||
// 从socket中读取数据
|
// 从socket中读取数据
|
||||||
@ -304,7 +304,7 @@ impl Syscall {
|
|||||||
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
let mut socket = socket.inner();
|
let mut socket = unsafe { socket.inner_no_preempt() };
|
||||||
socket.listen(backlog)?;
|
socket.listen(backlog)?;
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@ -319,7 +319,7 @@ impl Syscall {
|
|||||||
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
let socket = socket.inner();
|
let socket = unsafe { socket.inner_no_preempt() };
|
||||||
socket.shutdown(ShutdownType::try_from(how as i32)?)?;
|
socket.shutdown(ShutdownType::try_from(how as i32)?)?;
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@ -336,7 +336,7 @@ impl Syscall {
|
|||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
// kdebug!("accept: socket={:?}", socket);
|
// kdebug!("accept: socket={:?}", socket);
|
||||||
let mut socket = socket.inner();
|
let mut socket = unsafe { socket.inner_no_preempt() };
|
||||||
// 从socket中接收连接
|
// 从socket中接收连接
|
||||||
let (new_socket, remote_endpoint) = socket.accept()?;
|
let (new_socket, remote_endpoint) = socket.accept()?;
|
||||||
drop(socket);
|
drop(socket);
|
||||||
|
@ -37,8 +37,10 @@ impl ProcessManager {
|
|||||||
let stack_ptr =
|
let stack_ptr =
|
||||||
VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1)));
|
VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1)));
|
||||||
// 初始化bsp的idle进程
|
// 初始化bsp的idle进程
|
||||||
unsafe { KernelStack::from_existed(stack_ptr) }
|
let mut ks = unsafe { KernelStack::from_existed(stack_ptr) }
|
||||||
.expect("Failed to create kernel stack struct for BSP.")
|
.expect("Failed to create kernel stack struct for BSP.");
|
||||||
|
unsafe { ks.clear_pcb(true) };
|
||||||
|
ks
|
||||||
} else {
|
} else {
|
||||||
KernelStack::new().unwrap_or_else(|e| {
|
KernelStack::new().unwrap_or_else(|e| {
|
||||||
panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e)
|
panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e)
|
||||||
|
@ -34,7 +34,7 @@ use crate::{
|
|||||||
constant::{FutexFlag, FUTEX_BITSET_MATCH_ANY},
|
constant::{FutexFlag, FUTEX_BITSET_MATCH_ANY},
|
||||||
futex::Futex,
|
futex::Futex,
|
||||||
},
|
},
|
||||||
rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
|
rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
|
||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
wait_queue::WaitQueue,
|
wait_queue::WaitQueue,
|
||||||
},
|
},
|
||||||
@ -235,6 +235,7 @@ impl ProcessManager {
|
|||||||
///
|
///
|
||||||
/// - 进入当前函数之前,不能持有sched_info的锁
|
/// - 进入当前函数之前,不能持有sched_info的锁
|
||||||
/// - 进入当前函数之前,必须关闭中断
|
/// - 进入当前函数之前,必须关闭中断
|
||||||
|
/// - 进入当前函数之后必须保证逻辑的正确性,避免被重复加入调度队列
|
||||||
pub fn mark_sleep(interruptable: bool) -> Result<(), SystemError> {
|
pub fn mark_sleep(interruptable: bool) -> Result<(), SystemError> {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
CurrentIrqArch::is_irq_enabled(),
|
CurrentIrqArch::is_irq_enabled(),
|
||||||
@ -692,6 +693,17 @@ impl ProcessControlBlock {
|
|||||||
return self.sched_info.read();
|
return self.sched_info.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn sched_info_irqsave(&self) -> RwLockReadGuard<ProcessSchedulerInfo> {
|
||||||
|
return self.sched_info.read_irqsave();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn sched_info_upgradeable_irqsave(&self) -> RwLockUpgradableGuard<ProcessSchedulerInfo> {
|
||||||
|
return self.sched_info.upgradeable_read();
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn sched_info_mut(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> {
|
pub fn sched_info_mut(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> {
|
||||||
return self.sched_info.write();
|
return self.sched_info.write();
|
||||||
@ -977,7 +989,7 @@ impl ProcessSchedulerInfo {
|
|||||||
return self.state;
|
return self.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_state(&mut self, state: ProcessState) {
|
pub fn set_state(&mut self, state: ProcessState) {
|
||||||
self.state = state;
|
self.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,6 +1081,7 @@ impl KernelStack {
|
|||||||
|
|
||||||
// 如果内核栈的最低地址处已经有了一个pcb,那么,这里就不再设置,直接返回错误
|
// 如果内核栈的最低地址处已经有了一个pcb,那么,这里就不再设置,直接返回错误
|
||||||
if unlikely(unsafe { !(*stack_bottom_ptr).is_null() }) {
|
if unlikely(unsafe { !(*stack_bottom_ptr).is_null() }) {
|
||||||
|
kerror!("kernel stack bottom is not null: {:p}", *stack_bottom_ptr);
|
||||||
return Err(SystemError::EPERM);
|
return Err(SystemError::EPERM);
|
||||||
}
|
}
|
||||||
// 将pcb的地址放到内核栈的最低地址处
|
// 将pcb的地址放到内核栈的最低地址处
|
||||||
@ -1079,6 +1092,25 @@ impl KernelStack {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 清除内核栈的pcb指针
|
||||||
|
///
|
||||||
|
/// ## 参数
|
||||||
|
///
|
||||||
|
/// - `force` : 如果为true,那么,即使该内核栈的pcb指针不为null,也会被强制清除而不处理Weak指针问题
|
||||||
|
pub unsafe fn clear_pcb(&mut self, force: bool) {
|
||||||
|
let stack_bottom_ptr = self.start_address().data() as *mut *const ProcessControlBlock;
|
||||||
|
if unlikely(unsafe { (*stack_bottom_ptr).is_null() }) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !force {
|
||||||
|
let pcb_ptr: Weak<ProcessControlBlock> = Weak::from_raw(*stack_bottom_ptr);
|
||||||
|
drop(pcb_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
*stack_bottom_ptr = core::ptr::null();
|
||||||
|
}
|
||||||
|
|
||||||
/// 返回指向当前内核栈pcb的Arc指针
|
/// 返回指向当前内核栈pcb的Arc指针
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub unsafe fn pcb(&self) -> Option<Arc<ProcessControlBlock>> {
|
pub unsafe fn pcb(&self) -> Option<Arc<ProcessControlBlock>> {
|
||||||
|
@ -98,6 +98,24 @@ pub trait Scheduler {
|
|||||||
pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
|
pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
|
||||||
// 当前进程持有锁,不切换,避免死锁
|
// 当前进程持有锁,不切换,避免死锁
|
||||||
if ProcessManager::current_pcb().preempt_count() != 0 {
|
if ProcessManager::current_pcb().preempt_count() != 0 {
|
||||||
|
let binding = ProcessManager::current_pcb();
|
||||||
|
let mut guard = binding.sched_info_upgradeable_irqsave();
|
||||||
|
let state = guard.state();
|
||||||
|
if state.is_blocked() {
|
||||||
|
// try to upgrade
|
||||||
|
for _ in 0..50 {
|
||||||
|
match guard.try_upgrade() {
|
||||||
|
Ok(mut writer) => {
|
||||||
|
// 被mark_sleep但是还在临界区的进程将其设置为Runnable
|
||||||
|
writer.set_state(ProcessState::Runnable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(s) => {
|
||||||
|
guard = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
3
tools/.gitignore
vendored
3
tools/.gitignore
vendored
@ -5,4 +5,5 @@ arch/i386/efi/grub/*
|
|||||||
arch/x86_64/efi/grub/*
|
arch/x86_64/efi/grub/*
|
||||||
|
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
build/*
|
build/*
|
||||||
|
target/
|
@ -48,8 +48,8 @@ EOF
|
|||||||
|
|
||||||
echo "Creating virtual disk image..."
|
echo "Creating virtual disk image..."
|
||||||
ARGS=`getopt -o P: -- "$@"`
|
ARGS=`getopt -o P: -- "$@"`
|
||||||
# 创建一至少为64MB磁盘镜像(类型选择raw)
|
# 创建一至少为256MB磁盘镜像(类型选择raw)
|
||||||
qemu-img create -f raw disk.img 64M
|
qemu-img create -f raw disk.img 256M
|
||||||
#将规范化后的命令行参数分配至位置参数($1,$2,...)
|
#将规范化后的命令行参数分配至位置参数($1,$2,...)
|
||||||
eval set -- "${ARGS}"
|
eval set -- "${ARGS}"
|
||||||
#echo formatted parameters=[$@]
|
#echo formatted parameters=[$@]
|
||||||
|
@ -62,9 +62,9 @@ QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
|
|||||||
|
|
||||||
# ps: 下面这条使用tap的方式,无法dhcp获取到ip,暂时不知道为什么
|
# ps: 下面这条使用tap的方式,无法dhcp获取到ip,暂时不知道为什么
|
||||||
# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||||
# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||||
# E1000E
|
# E1000E
|
||||||
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
#QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||||
QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
|
QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
|
||||||
|
|
||||||
QEMU_ARGUMENT+="-s -S -enable-kvm -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
|
QEMU_ARGUMENT+="-s -S -enable-kvm -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user