Skip to main content

starnix_core/task/
run_state.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::task::{Waiter, WaiterRef};
6use starnix_sync::InterruptibleEvent;
7use std::sync::Arc;
8
9/// Whether, and how, this task is blocked. This enum can be extended with new
10/// variants to optimize different kinds of waiting.
11#[derive(Debug, Clone)]
12pub enum RunState {
13    /// This task is not blocked.
14    ///
15    /// The task might be running in userspace or kernel.
16    Running,
17
18    /// This thread is blocked in a `Waiter`.
19    Waiter(WaiterRef),
20
21    /// This thread is blocked in an `InterruptibleEvent`.
22    Event(Arc<InterruptibleEvent>),
23
24    /// This thread is frozen by a `Waiter`.
25    ///
26    /// When waiting on the `Waiter`, it should have a loop to prevent any signals except
27    /// notification.
28    Frozen(Waiter),
29}
30
31impl Default for RunState {
32    fn default() -> Self {
33        RunState::Running
34    }
35}
36
37impl RunState {
38    /// Whether this task is blocked.
39    ///
40    /// If the task is blocked, you can break the task out of the wait using the `wake` function.
41    pub fn is_blocked(&self) -> bool {
42        match self {
43            RunState::Running => false,
44            RunState::Waiter(waiter) => waiter.is_valid(),
45            RunState::Event(_) | RunState::Frozen(_) => true,
46        }
47    }
48
49    /// Unblock the task by interrupting whatever wait the task is blocked upon.
50    pub fn wake(&self) {
51        match self {
52            RunState::Running => (),
53            RunState::Waiter(waiter) => waiter.interrupt(),
54            RunState::Event(event) => event.interrupt(),
55            // When frozen, the task immunes to any interrupts.
56            RunState::Frozen(_) => (),
57        }
58    }
59}
60
61impl PartialEq<RunState> for RunState {
62    fn eq(&self, other: &RunState) -> bool {
63        match (self, other) {
64            (RunState::Running, RunState::Running) => true,
65            (RunState::Waiter(lhs), RunState::Waiter(rhs)) => lhs == rhs,
66            (RunState::Event(lhs), RunState::Event(rhs)) => Arc::ptr_eq(lhs, rhs),
67            (RunState::Frozen(lhs), RunState::Frozen(rhs)) => lhs == rhs,
68            _ => false,
69        }
70    }
71}