Skip to main content

Thread

Struct Thread 

Source
pub struct Thread { /* private fields */ }
Expand description

Thread/task management and notification types. A schedulable unit of execution backed by a POSIX thread (pthread_t).

Created in a “not yet spawned” state via Thread::new, and only backed by a real OS thread once ThreadFn::spawn/ThreadFn::spawn_simple is called on it. See Thread::new for a complete, testable example.

Implementations§

Source§

impl Thread

Source

pub fn new(name: &str, stack_depth: StackType, priority: UBaseType) -> Self

Describes a not-yet-spawned thread: name/stack_depth/priority are recorded now and used when ThreadFn::spawn/spawn_simple is called on it. ThreadFn::is_null is true until then.

§Examples
use osal_rs::os::*;

let thread = Thread::new("worker", 1024, 5);
assert!(thread.is_null());
Source

pub fn new_with_handle( handle: ThreadHandle, name: &str, stack_depth: StackType, priority: UBaseType, ) -> Result<Self>

Wraps an already-running thread’s handle (e.g. one obtained from ThreadFn::get_current), rather than spawning a new one. Fails with Error::NullPtr if handle is the null sentinel (0).

§Examples
use osal_rs::os::*;

let current = Thread::get_current();
let wrapped = Thread::new_with_handle(*current, "current", 0, 0).unwrap();
assert!(!wrapped.is_null());
Source

pub fn new_with_to_priority( name: &str, stack_depth: StackType, priority: impl ToPriority, ) -> Self

Same as Thread::new, but accepts any ToPriority value instead of a raw UBaseType priority.

§Examples
use osal_rs::os::*;
use osal_rs::os::types::UBaseType;

enum Priority { High }

impl ToPriority for Priority {
    fn to_priority(&self) -> UBaseType { 5 }
}

let thread = Thread::new_with_to_priority("worker", 1024, Priority::High);
assert!(thread.is_null());
Source

pub fn new_with_handle_and_to_priority( handle: ThreadHandle, name: &str, stack_depth: StackType, priority: impl ToPriority, ) -> Result<Self>

Same as Thread::new_with_handle, but accepts any ToPriority value instead of a raw UBaseType priority.

§Examples
use osal_rs::os::*;
use osal_rs::os::types::UBaseType;

enum Priority { Normal }

impl ToPriority for Priority {
    fn to_priority(&self) -> UBaseType { 0 }
}

let current = Thread::get_current();
let wrapped = Thread::new_with_handle_and_to_priority(*current, "current", 0, Priority::Normal).unwrap();
assert!(!wrapped.is_null());
Source

pub fn get_metadata_from_handle(handle: ThreadHandle) -> ThreadMetadata

Looks up a ThreadMetadata snapshot for a raw ThreadHandle, without needing a Thread value. Used by crate::os::SystemFn::get_all_thread to report threads it only knows by handle.

§Examples
use osal_rs::os::*;

let current = Thread::get_current();
let metadata = Thread::get_metadata_from_handle(*current);
assert_eq!(metadata.thread, *current);
Source

pub fn get_metadata(thread: &Thread) -> ThreadMetadata

Builds a ThreadMetadata snapshot from a Thread value directly - same information as Thread::get_metadata_from_handle, but also works for a not-yet-spawned thread (reported as ThreadState::Invalid).

§Examples
use osal_rs::os::*;

let thread = Thread::new("worker", 1024, 3);
let metadata = Thread::get_metadata(&thread);
assert_eq!(metadata.state, ThreadState::Invalid);
assert_eq!(metadata.priority, 3);
Source

pub fn wait_notification_with_to_tick( &self, bits_to_clear_on_entry: u32, bits_to_clear_on_exit: u32, timeout_ticks: impl ToTick, ) -> Result<u32>

Blocks like ThreadFn::wait_notification, but accepts any ToTick timeout (e.g. a core::time::Duration) instead of a raw tick count.

§Examples
use osal_rs::os::*;
use core::time::Duration;

let current = Thread::get_current();
current.notify(ThreadNotification::SetValueWithOverwrite(7)).unwrap();

let value = current.wait_notification_with_to_tick(0, 0, Duration::from_millis(50)).unwrap();
assert_eq!(value, 7);

Trait Implementations§

Source§

impl Clone for Thread

Source§

fn clone(&self) -> Thread

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Thread

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Deref for Thread

Source§

type Target = u64

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl Display for Thread

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Send for Thread

Source§

impl Sync for Thread

Source§

impl Thread for Thread

Source§

fn is_null(&self) -> bool

Returns true if this handle refers to no thread - either Thread::new was never followed by spawn/spawn_simple, or the pthread ID happens to be the reserved 0 sentinel.

§Examples
use osal_rs::os::*;

let thread = Thread::new("worker", 1024, 5);
assert!(thread.is_null());
Source§

fn spawn<F>(&mut self, param: Option<ThreadParam>, callback: F) -> Result<Self>
where F: Fn(Box<dyn ThreadFn>, Option<ThreadParam>) -> Result<ThreadParam> + Send + Sync + 'static, Self: Sized,

Spawns a new pthread running callback(self_handle, param), passing through an arbitrary ThreadParam (an Arc<dyn Any + Send + Sync>) that the callback can downcast back to its concrete type. Prefer ThreadFn::spawn_simple when no parameter is needed.

§Examples
use osal_rs::os::*;
use std::sync::Arc;
use std::sync::atomic::{AtomicI32, Ordering};

static RECEIVED: AtomicI32 = AtomicI32::new(0);

let mut thread = Thread::new("worker", 1024, 5);
let param: ThreadParam = Arc::new(42i32);

let spawned = thread.spawn(Some(param), |_handle, param| {
    if let Some(value) = param.and_then(|p| p.downcast_ref::<i32>().copied()) {
        RECEIVED.store(value, Ordering::SeqCst);
    }
    Ok(Arc::new(()))
}).unwrap();

spawned.join(core::ptr::null_mut()).unwrap();
assert_eq!(RECEIVED.load(Ordering::SeqCst), 42);
Source§

fn spawn_simple<F>(&mut self, callback: F) -> Result<Self>
where F: Fn() -> Result<ThreadParam> + Send + Sync + 'static, Self: Sized,

Spawns a new pthread running callback(). Simpler than ThreadFn::spawn when no parameter needs to be passed in.

§Examples
use osal_rs::os::*;
use std::sync::Arc;

let mut thread = Thread::new("worker", 1024, 5);
let spawned = thread.spawn_simple(|| {
    println!("Working...");
    Ok(Arc::new(()))
}).unwrap();

spawned.join(core::ptr::null_mut()).unwrap();
Source§

fn delete(&self)

Joins the thread (blocking until it finishes) and forgets its registry/notification-slot entries, discarding any error from the underlying pthread_join. Prefer ThreadFn::join when the exit status matters.

§Examples
use osal_rs::os::*;
use std::sync::Arc;

let mut thread = Thread::new("worker", 1024, 5);
let spawned = thread.spawn_simple(|| Ok(Arc::new(()))).unwrap();
spawned.delete();
Source§

fn suspend(&self)

Suspends the thread by sending it a dedicated real-time signal that parks it until ThreadFn::resume sends the matching wake-up signal (pthreads has no native suspend/resume of its own). A no-op if this handle ThreadFn::is_null.

§Examples
use osal_rs::os::*;
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};

static COUNTER: AtomicU32 = AtomicU32::new(0);

let mut thread = Thread::new("counter", 1024, 1);
let worker = thread.spawn_simple(|| {
    loop {
        COUNTER.fetch_add(1, Ordering::SeqCst);
        System::delay(1);
    }
}).unwrap();

System::delay(30);
worker.suspend();

let paused_at = COUNTER.load(Ordering::SeqCst);
System::delay(50);
// No progress while suspended.
assert_eq!(COUNTER.load(Ordering::SeqCst), paused_at);

worker.resume();
System::delay(30);
// Progress resumes.
assert!(COUNTER.load(Ordering::SeqCst) > paused_at);
Source§

fn resume(&self)

Resumes a thread previously suspended with ThreadFn::suspend. See ThreadFn::suspend for a complete example. A no-op if this handle ThreadFn::is_null.

Source§

fn join(&self, ret_val: DoublePtr) -> Result<i32>

Blocks until the thread finishes, writing its exit value (boxed by ThreadFn::spawn/spawn_simple) to *ret_val if non-null. Fails with Error::NullPtr if this handle ThreadFn::is_null.

§Examples
use osal_rs::os::*;
use std::sync::Arc;

let mut thread = Thread::new("worker", 1024, 5);
let spawned = thread.spawn_simple(|| Ok(Arc::new(()))).unwrap();
assert!(spawned.join(core::ptr::null_mut()).is_ok());
Source§

fn get_metadata(&self) -> ThreadMetadata

Returns a ThreadMetadata snapshot for this thread. See Thread::get_metadata (the inherent, static-style helper this delegates to) for a complete example.

Source§

fn get_current() -> Self
where Self: Sized,

Returns a Thread handle for the calling thread itself - works whether called from the “main” thread or from inside a callback running on a thread this crate spawned.

§Examples
use osal_rs::os::*;

let current = Thread::get_current();
assert!(!current.is_null());
Source§

fn notify(&self, notification: ThreadNotification) -> Result<()>

Sets or updates this thread’s single-slot notification value (see ThreadNotification for the available update strategies) and wakes it if it’s blocked in ThreadFn::wait_notification.

§Examples
use osal_rs::os::*;

let current = Thread::get_current();
current.notify(ThreadNotification::SetValueWithOverwrite(5)).unwrap();

let value = current.wait_notification(0, 0, 0).unwrap();
assert_eq!(value, 5);
Source§

fn notify_from_isr( &self, notification: ThreadNotification, higher_priority_task_woken: &mut BaseType, ) -> Result<()>

ISR-safe variant of ThreadFn::notify; identical on POSIX (there is no real interrupt context, and thus no scheduler decision to report back through higher_priority_task_woken, which is always set to 0).

§Examples
use osal_rs::os::*;

let current = Thread::get_current();
let mut woken = 0;
current.notify_from_isr(ThreadNotification::Increment, &mut woken).unwrap();
assert_eq!(woken, 0);

let value = current.wait_notification(0, 0, 0).unwrap();
assert_eq!(value, 1);
Source§

fn wait_notification( &self, bits_to_clear_on_entry: u32, bits_to_clear_on_exit: u32, timeout_ticks: TickType, ) -> Result<u32>

Blocks until a notification is pending or timeout_ticks elapses (pass TickType::MAX to wait forever), returning the notification value. bits_to_clear_on_entry/bits_to_clear_on_exit clear the matching bits from the value before waiting/before returning, respectively. Fails with Error::Timeout on timeout.

§Examples
use osal_rs::os::*;

let current = Thread::get_current();

// Nothing notified yet: times out instead of blocking forever.
assert!(current.wait_notification(0, 0, 10).is_err());

current.notify(ThreadNotification::SetValueWithOverwrite(9)).unwrap();
assert_eq!(current.wait_notification(0, 0, 10).unwrap(), 9);

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.