blob: 682fe9f5aa32154e9b40b81f67881af03b2827cc [file]
// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::task::{Waiter, WaiterRef};
use starnix_sync::InterruptibleEvent;
use std::sync::Arc;
/// Whether, and how, this task is blocked. This enum can be extended with new
/// variants to optimize different kinds of waiting.
#[derive(Debug, Clone)]
pub enum RunState {
/// This task is not blocked.
///
/// The task might be running in userspace or kernel.
Running,
/// This thread is blocked in a `Waiter`.
Waiter(WaiterRef),
/// This thread is blocked in an `InterruptibleEvent`.
Event(Arc<InterruptibleEvent>),
/// This thread is frozen by a `Waiter`.
///
/// When waiting on the `Waiter`, it should have a loop to prevent any signals except
/// notification.
Frozen(Waiter),
}
impl Default for RunState {
fn default() -> Self {
RunState::Running
}
}
impl RunState {
/// Whether this task is blocked.
///
/// If the task is blocked, you can break the task out of the wait using the `wake` function.
pub fn is_blocked(&self) -> bool {
match self {
RunState::Running => false,
RunState::Waiter(waiter) => waiter.is_valid(),
RunState::Event(_) | RunState::Frozen(_) => true,
}
}
/// Unblock the task by interrupting whatever wait the task is blocked upon.
pub fn wake(&self) {
match self {
RunState::Running => (),
RunState::Waiter(waiter) => waiter.interrupt(),
RunState::Event(event) => event.interrupt(),
// When frozen, the task immunes to any interrupts.
RunState::Frozen(_) => (),
}
}
}
impl PartialEq<RunState> for RunState {
fn eq(&self, other: &RunState) -> bool {
match (self, other) {
(RunState::Running, RunState::Running) => true,
(RunState::Waiter(lhs), RunState::Waiter(rhs)) => lhs == rhs,
(RunState::Event(lhs), RunState::Event(rhs)) => Arc::ptr_eq(lhs, rhs),
(RunState::Frozen(lhs), RunState::Frozen(rhs)) => lhs == rhs,
_ => false,
}
}
}