pub struct AtomicThreadState(/* private fields */);full only.Expand description
An atomic version of ThreadState.
Implementations§
Source§impl AtomicThreadState
impl AtomicThreadState
Sourcepub const fn new(state: ThreadState) -> Self
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());Sourcepub fn store(&self, state: ThreadState, ordering: Ordering)
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());Sourcepub fn load(&self, ordering: Ordering) -> ThreadState
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);Sourcepub fn compare_exchange(
&self,
current: ThreadState,
new: ThreadState,
success: Ordering,
failure: Ordering,
) -> Result<ThreadState, ThreadState>
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);Sourcepub fn fetch_update(
&self,
set_order: Ordering,
fetch_order: Ordering,
f: impl FnMut(ThreadState) -> Option<ThreadState>,
) -> Result<ThreadState, ThreadState>
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));Sourcepub fn running(&self) -> bool
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());Sourcepub fn runnable(&self) -> bool
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());