Skip to main content

AtomicThreadState

Struct AtomicThreadState 

Source
pub struct AtomicThreadState(/* private fields */);
Available on crate feature full only.
Expand description

An atomic version of ThreadState.

Implementations§

Source§

impl AtomicThreadState

Source

pub const fn new(state: ThreadState) -> Self

Creates a new AtomicThreadState from the given ThreadState.

§Examples
use kernel_api::threading::{ThreadState, AtomicThreadState};

let state = AtomicThreadState::new(ThreadState::Running);
assert!(state.running());
Source

pub fn store(&self, state: ThreadState, ordering: Ordering)

Atomically updates self to state.

store takes an [Ordering] argument which describes the memory ordering of this operation. Possible values are SeqCst, Release and Relaxed.

§Panics

Panics if ordering is Acquire or AcqRel.

§Examples
use kernel_api::threading::{ThreadState, AtomicThreadState};
use core::sync::atomic::Ordering;

let state = AtomicThreadState::new(ThreadState::Running);
assert!(state.running());
state.store(ThreadState::Killed(-1), Ordering::SeqCst);
assert!(!state.running());
Source

pub fn load(&self, ordering: Ordering) -> ThreadState

Atomically retrieves the current state of self.

load takes an [Ordering] argument which describes the memory ordering of this operation. Possible values are SeqCst, Acquire and Relaxed.

§Panics

Panics if ordering is Release or AcqRel.

§Examples
use kernel_api::threading::{ThreadState, AtomicThreadState};
use core::sync::atomic::Ordering;
use core::assert_matches;

let state = AtomicThreadState::new(ThreadState::Running);
let state = state.load(Ordering::SeqCst);
assert_matches!(state, ThreadState::Running);
Source

pub fn compare_exchange( &self, current: ThreadState, new: ThreadState, success: Ordering, failure: Ordering, ) -> Result<ThreadState, ThreadState>

Stores a value into the thread state if the current state is the same as the current state.

The return value is a result indicating whether the new state was written and containing the previous state. On success this value is guaranteed to be equal to current.

compare_exchange takes two [Ordering] arguments to describe the memory ordering of this operation. success describes the required ordering for the read-modify-write operation that takes place if the comparison with current succeeds. failure describes the required ordering for the load operation that takes place when the comparison fails. Using Acquire as success ordering makes the store part of this operation Relaxed, and using Release makes the successful load Relaxed. The failure ordering can only be SeqCst, Acquire or Relaxed.

§Examples
use kernel_api::threading::{ThreadState, AtomicThreadState};
use core::sync::atomic::Ordering;

let state = AtomicThreadState::new(ThreadState::Killed(0));

assert_eq!(state.compare_exchange(ThreadState::Killed(0), ThreadState::Running,
                                     Ordering::Acquire,
                                     Ordering::Relaxed),
           Ok(ThreadState::Killed(0)));
assert_eq!(some_var.load(Ordering::Relaxed), ThreadState::Running);

assert_eq!(some_var.compare_exchange(ThreadState::Runnable, ThreadState::Parked,
                                     Ordering::SeqCst,
                                     Ordering::Acquire),
           Err(ThreadState::Running));
assert_eq!(some_var.load(Ordering::Relaxed), ThreadState::Running);
Source

pub fn fetch_update( &self, set_order: Ordering, fetch_order: Ordering, f: impl FnMut(ThreadState) -> Option<ThreadState>, ) -> Result<ThreadState, ThreadState>

Fetches the current state, and applies a function to it that returns an optional new state. Returns a Result of Ok(previous_state) if the function returned Some(_), else Err(previous_state).

Note: This may call the function multiple times if the value has been changed from other threads in the meantime, as long as the function returns Some(_), but the function will have been applied only once to the stored value.

fetch_update takes two [Ordering] arguments to describe the memory ordering of this operation. The first describes the required ordering for when the operation finally succeeds while the second describes the required ordering for loads. These correspond to the success and failure orderings of [compare_exchange] respectively.

Using Acquire as success ordering makes the store part of this operation Relaxed, and using Release makes the final successful load Relaxed. The (failed) load ordering can only be SeqCst, Acquire or Relaxed.

§Examples
use kernel_api::threading::{ThreadState, AtomicThreadState};
use core::sync::atomic::Ordering;

let state = AtomicThreadState::new(ThreadState::Killed(0));
assert_eq!(state.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ThreadState::Running));
assert_eq!(
    state.fetch_update(
        Ordering::SeqCst,
        Ordering::SeqCst,
        |old_state| {
            match old_state {
                ThreadState::Killed(code) => Some(ThreadState::Killed(code + 1)),
                _ => None,
            }
        }
    ),
    Ok(ThreadState::Killed(0))
);
assert_eq!(state.load(Ordering::SeqCst), ThreadState::Killed(1));
Source

pub fn running(&self) -> bool

Returns true if the thread is actively running.

§Examples
use kernel_api::threading::{ThreadState, AtomicThreadState};

let running = AtomicThreadState::new(ThreadState::Running);
assert!(running.running());

let dead = AtomicThreadState::new(ThreadState::Killed(0));
assert!(!dead.running());
Source

pub fn runnable(&self) -> bool

Returns true if the thread could be run in its current state.

§Examples
use kernel_api::threading::{ThreadState, AtomicThreadState};

let runnable = AtomicThreadState::new(ThreadState::Runnable);
assert!(runnable.runnable());

let dead = AtomicThreadState::new(ThreadState::Killed(0));
assert!(!dead.runnable());

Trait Implementations§

Source§

impl Debug for AtomicThreadState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for AtomicThreadState

§

impl RefUnwindSafe for AtomicThreadState

§

impl Send for AtomicThreadState

§

impl Sync for AtomicThreadState

§

impl Unpin for AtomicThreadState

§

impl UnsafeUnpin for AtomicThreadState

§

impl UnwindSafe for AtomicThreadState

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = !

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.