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}