123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- use core::intrinsics::unlikely;
- use alloc::{collections::VecDeque, sync::Arc, vec::Vec};
- use log::{error, warn};
- use system_error::SystemError;
- use crate::{
- arch::{ipc::signal::Signal, CurrentIrqArch},
- exception::InterruptArch,
- process::{ProcessControlBlock, ProcessManager, ProcessState},
- sched::{schedule, SchedMode},
- };
- use super::{
- mutex::MutexGuard,
- spinlock::{SpinLock, SpinLockGuard},
- };
- #[derive(Debug)]
- struct InnerWaitQueue {
-
- dead: bool,
-
- wait_list: VecDeque<Arc<ProcessControlBlock>>,
- }
- #[derive(Debug)]
- pub struct WaitQueue {
- inner: SpinLock<InnerWaitQueue>,
- }
- #[allow(dead_code)]
- impl WaitQueue {
- pub const fn default() -> Self {
- WaitQueue {
- inner: SpinLock::new(InnerWaitQueue::INIT),
- }
- }
- fn inner_irqsave(&self) -> SpinLockGuard<InnerWaitQueue> {
- self.inner.lock_irqsave()
- }
- fn inner(&self) -> SpinLockGuard<InnerWaitQueue> {
- self.inner.lock()
- }
- pub fn prepare_to_wait_event(&self, interruptible: bool) -> Result<(), SystemError> {
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- let pcb = ProcessManager::current_pcb();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- if Signal::signal_pending_state(interruptible, false, &pcb) {
- return Err(SystemError::ERESTARTSYS);
- } else {
- ProcessManager::mark_sleep(interruptible).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(guard);
- }
- Ok(())
- }
- pub fn finish_wait(&self) {
- let pcb = ProcessManager::current_pcb();
- let mut writer = pcb.sched_info().inner_lock_write_irqsave();
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- writer.set_state(ProcessState::Runnable);
- writer.set_wakeup();
- guard.wait_list.retain(|x| !Arc::ptr_eq(x, &pcb));
- drop(guard);
- drop(writer);
- }
-
- pub fn sleep(&self) -> Result<(), SystemError> {
- before_sleep_check(0);
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(guard);
- schedule(SchedMode::SM_NONE);
- Ok(())
- }
-
- pub fn mark_dead(&self) {
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- guard.dead = true;
- drop(guard);
- }
-
- pub fn sleep_with_func<F>(&self, f: F) -> Result<(), SystemError>
- where
- F: FnOnce(),
- {
- before_sleep_check(0);
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- f();
- drop(guard);
- schedule(SchedMode::SM_NONE);
- Ok(())
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- pub unsafe fn sleep_without_schedule(&self) -> Result<(), SystemError> {
- before_sleep_check(1);
-
- assert!(!CurrentIrqArch::is_irq_enabled());
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(guard);
- Ok(())
- }
- pub unsafe fn sleep_without_schedule_uninterruptible(&self) -> Result<(), SystemError> {
- before_sleep_check(1);
-
- assert!(!CurrentIrqArch::is_irq_enabled());
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(guard);
- Ok(())
- }
-
- pub fn sleep_uninterruptible(&self) -> Result<(), SystemError> {
- before_sleep_check(0);
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(guard);
- schedule(SchedMode::SM_NONE);
- Ok(())
- }
-
-
- pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) -> Result<(), SystemError> {
- before_sleep_check(1);
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(to_unlock);
- drop(guard);
- schedule(SchedMode::SM_NONE);
- Ok(())
- }
-
-
- pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) -> Result<(), SystemError> {
- before_sleep_check(1);
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- if !guard.can_sleep() {
- return Err(SystemError::ESRCH);
- }
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(to_unlock);
- drop(guard);
- schedule(SchedMode::SM_NONE);
- Ok(())
- }
-
-
- pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
- before_sleep_check(1);
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
- ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- drop(irq_guard);
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(to_unlock);
- drop(guard);
- schedule(SchedMode::SM_NONE);
- }
-
-
- pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
- before_sleep_check(1);
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
- let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
- ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- drop(irq_guard);
- guard.wait_list.push_back(ProcessManager::current_pcb());
- drop(to_unlock);
- drop(guard);
- schedule(SchedMode::SM_NONE);
- }
-
-
-
-
-
-
-
- pub fn wakeup(&self, state: Option<ProcessState>) -> bool {
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
-
- if guard.wait_list.is_empty() {
- return false;
- }
-
- if let Some(state) = state {
- if guard
- .wait_list
- .front()
- .unwrap()
- .sched_info()
- .inner_lock_read_irqsave()
- .state()
- != state
- {
- return false;
- }
- }
- let to_wakeup = guard.wait_list.pop_front().unwrap();
- drop(guard);
- let res = ProcessManager::wakeup(&to_wakeup).is_ok();
- return res;
- }
-
-
-
- pub fn wakeup_all(&self, state: Option<ProcessState>) {
- let mut guard: SpinLockGuard<InnerWaitQueue> = self.inner_irqsave();
-
- if guard.wait_list.is_empty() {
- return;
- }
- let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new();
-
- while let Some(to_wakeup) = guard.wait_list.pop_front() {
- let mut wake = false;
- if let Some(state) = state {
- if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state {
- wake = true;
- }
- } else {
- wake = true;
- }
- if wake {
- ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| {
- error!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e);
- });
- continue;
- } else {
- to_push_back.push(to_wakeup);
- }
- }
- for to_wakeup in to_push_back {
- guard.wait_list.push_back(to_wakeup);
- }
- }
-
- pub fn len(&self) -> usize {
- return self.inner_irqsave().wait_list.len();
- }
- }
- impl InnerWaitQueue {
- pub const INIT: InnerWaitQueue = InnerWaitQueue {
- wait_list: VecDeque::new(),
- dead: false,
- };
- pub fn can_sleep(&self) -> bool {
- return !self.dead;
- }
- }
- fn before_sleep_check(max_preempt: usize) {
- let pcb = ProcessManager::current_pcb();
- if unlikely(pcb.preempt_count() > max_preempt) {
- warn!(
- "Process {:?}: Try to sleep when preempt count is {}",
- pcb.pid().data(),
- pcb.preempt_count()
- );
- }
- }
- #[derive(Debug)]
- pub struct EventWaitQueue {
- wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>,
- }
- impl Default for EventWaitQueue {
- fn default() -> Self {
- Self::new()
- }
- }
- #[allow(dead_code)]
- impl EventWaitQueue {
- pub fn new() -> Self {
- Self {
- wait_list: SpinLock::new(Default::default()),
- }
- }
-
-
-
-
-
-
- pub fn sleep(&self, events: u64) {
- before_sleep_check(0);
- let mut guard = self.wait_list.lock_irqsave();
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.push((events, ProcessManager::current_pcb()));
- drop(guard);
- schedule(SchedMode::SM_NONE);
- }
- pub unsafe fn sleep_without_schedule(&self, events: u64) {
- before_sleep_check(1);
- let mut guard = self.wait_list.lock_irqsave();
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- guard.push((events, ProcessManager::current_pcb()));
- drop(guard);
- }
- pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) {
- before_sleep_check(1);
- let mut guard = self.wait_list.lock_irqsave();
- let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
- ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
- panic!("sleep error: {:?}", e);
- });
- drop(irq_guard);
- guard.push((events, ProcessManager::current_pcb()));
- drop(to_unlock);
- drop(guard);
- schedule(SchedMode::SM_NONE);
- }
-
-
-
-
-
-
- pub fn wakeup_any(&self, events: u64) -> usize {
- let mut ret = 0;
- let mut wq_guard = self.wait_list.lock_irqsave();
- wq_guard.retain(|(es, pcb)| {
- if *es & events > 0 {
-
- if ProcessManager::wakeup(pcb).is_ok() {
- ret += 1;
- return false;
- } else {
- return true;
- }
- } else {
- return true;
- }
- });
- ret
- }
-
-
-
-
-
-
- pub fn wakeup(&self, events: u64) -> usize {
- let mut ret = 0;
- let mut wq_guard = self.wait_list.lock_irqsave();
- wq_guard.retain(|(es, pcb)| {
- if *es == events {
-
- if ProcessManager::wakeup(pcb).is_ok() {
- ret += 1;
- return false;
- } else {
- return true;
- }
- } else {
- return true;
- }
- });
- ret
- }
- pub fn wakeup_all(&self) {
- self.wakeup_any(u64::MAX);
- }
- }
|