Skip to main content

ThreadFn

Trait ThreadFn 

Source
pub trait ThreadFn {
    // Required methods
    fn is_null(&self) -> bool;
    fn spawn<F>(
        &mut self,
        param: Option<ThreadParam>,
        callback: F,
    ) -> Result<Self>
       where F: Fn(Box<dyn Thread>, Option<ThreadParam>) -> Result<ThreadParam> + Send + Sync + 'static,
             Self: Sized;
    fn spawn_simple<F>(&mut self, callback: F) -> Result<Self>
       where F: Fn() -> Result<ThreadParam> + Send + Sync + 'static,
             Self: Sized;
    fn delete(&self);
    fn suspend(&self);
    fn resume(&self);
    fn join(&self, retval: DoublePtr) -> Result<i32>;
    fn get_metadata(&self) -> ThreadMetadata;
    fn get_current() -> Self
       where Self: Sized;
    fn notify(&self, notification: ThreadNotification) -> Result<()>;
    fn notify_from_isr(
        &self,
        notification: ThreadNotification,
        higher_priority_task_woken: &mut BaseType,
    ) -> Result<()>;
    fn wait_notification(
        &self,
        bits_to_clear_on_entry: u32,
        bits_to_clear_on_exit: u32,
        timeout_ticks: TickType,
    ) -> Result<u32>;
}
Expand description

All OSAL trait definitions for advanced usage. Core thread/task trait.

Provides methods for thread lifecycle management, synchronization, and communication through task notifications.

§Thread Creation

Threads are typically created with Thread::new() specifying name, stack size, and priority, then started with spawn() or spawn_simple().

§Thread Safety

All methods are thread-safe. ISR-specific methods (suffixed with _from_isr) should only be called from interrupt context.

§Resource Management

Threads should be properly deleted with delete() when no longer needed to free stack memory and control structures.

§Examples

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

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

// Create and spawn a simple thread
let mut thread = Thread::new("worker", 2048, 5);
let worker = thread.spawn_simple(|| {
    for _ in 0..3 {
        WORK.fetch_add(1, Ordering::SeqCst);
        System::delay(5);
    }
    Ok(Arc::new(()))
}).unwrap();

// Create thread with parameter
let mut thread2 = Thread::new("counter", 1024, 5);
let counter: ThreadParam = Arc::new(AtomicU32::new(0));
let counting = thread2.spawn(Some(counter.clone()), |_thread, param| {
    let param = param.unwrap();
    if let Some(count) = param.downcast_ref::<AtomicU32>() {
        count.fetch_add(1, Ordering::SeqCst);
    }
    Ok(param)
}).unwrap();

worker.delete();
counting.delete();

assert_eq!(WORK.load(Ordering::SeqCst), 3);
assert_eq!(counter.downcast_ref::<AtomicU32>().unwrap().load(Ordering::SeqCst), 1);

Required Methods§

Source

fn is_null(&self) -> bool

Returns true if the underlying OS handle is null, i.e. the thread has not been spawned yet or has already been deleted.

Source

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

Spawns a thread with a callback function and optional parameter.

Creates and starts a new thread that executes the provided callback function. The callback receives a handle to itself and an optional parameter.

§Parameters
  • param - Optional type-erased parameter passed to the callback
  • callback - Function to execute in the thread context
§Returns
  • Ok(Self) - Thread spawned successfully
  • Err(Error) - Failed to create or start thread
§Examples
use osal_rs::os::*;
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};

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

let mut thread = Thread::new("worker", 1024, 5);
let counter: ThreadParam = Arc::new(100u32);

let spawned = thread.spawn(Some(counter.clone()), |_thread, param| {
    if let Some(p) = param {
        if let Some(count) = p.downcast_ref::<u32>() {
            SEEN.store(*count, Ordering::SeqCst);
        }
    }
    Ok(Arc::new(200u32))
}).unwrap();

spawned.delete(); // waits for the thread to finish
assert_eq!(SEEN.load(Ordering::SeqCst), 100);
Source

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

Spawns a simple thread with a callback function (no parameters).

Creates and starts a new thread that executes the provided callback. This is a simpler version of spawn() for threads that don’t need parameters or self-reference.

§Parameters
  • callback - Function to execute in the thread context
§Returns
  • Ok(Self) - Thread spawned successfully
  • Err(Error) - Failed to create or start thread
§Examples
use osal_rs::os::*;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

static LED: AtomicBool = AtomicBool::new(false);

let mut thread = Thread::new("blinker", 512, 3);
let blinker = thread.spawn_simple(|| {
    for _ in 0..4 {
        LED.fetch_xor(true, Ordering::SeqCst); // toggle the LED
        System::delay(5);
    }
    Ok(Arc::new(()))
}).unwrap();

blinker.delete();
assert!(!LED.load(Ordering::SeqCst)); // toggled an even number of times
Source

fn delete(&self)

Deletes the thread and frees its resources.

Terminates the thread and releases its stack and control structures. After calling this, the thread handle becomes invalid.

§Safety
  • The thread should not be holding any resources (mutexes, etc.)
  • Other threads should not be waiting on this thread
  • Cannot delete the currently running thread (use from another thread)
§Examples
use osal_rs::os::*;
use std::sync::Arc;

let mut thread = Thread::new("temp", 512, 1);
let spawned = thread.spawn_simple(|| {
    // Do some work
    System::delay(5);
    Ok(Arc::new(()))
}).unwrap();

// Later, from another thread
spawned.delete();
Source

fn suspend(&self)

Suspends the thread.

Prevents the thread from executing until resume() is called. The thread state is preserved and can be resumed later.

§Use Cases
  • Temporarily pause a thread
  • Debugging and development
  • Dynamic task management
§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();  // Pauses the worker, not the caller

let paused_at = COUNTER.load(Ordering::SeqCst);
System::delay(50);

// No progress while suspended.
assert_eq!(COUNTER.load(Ordering::SeqCst), paused_at);

worker.resume();
Source

fn resume(&self)

Resumes a suspended thread.

Resumes execution of a thread that was previously suspended with suspend(). If the thread was not suspended, this has no effect.

§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 = thread.spawn_simple(|| {
    loop {
        COUNTER.fetch_add(1, Ordering::SeqCst);
        System::delay(1);
    }
}).unwrap();

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

let paused_at = COUNTER.load(Ordering::SeqCst);
System::delay(50);

worker_thread.resume();  // Resume the worker
System::delay(30);

// Progress resumes.
assert!(COUNTER.load(Ordering::SeqCst) > paused_at);
Source

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

Waits for the thread to complete and retrieves its return value.

Blocks the calling thread until this thread terminates. The thread’s return value is stored in the provided pointer.

§Parameters
  • retval - Pointer to store the thread’s return value
§Returns
  • Ok(exit_code) - Thread completed successfully
  • Err(Error) - Join operation failed
§Examples
use osal_rs::os::*;
use std::sync::Arc;

let mut thread = Thread::new("worker", 1024, 1);
let spawned = thread.spawn_simple(|| {
    // Do work
    Ok(Arc::new(()))
}).unwrap();

// Pass a null pointer when the exit value is not needed.
assert!(spawned.join(core::ptr::null_mut()).is_ok());
Source

fn get_metadata(&self) -> ThreadMetadata

Gets metadata about the thread.

Returns information such as thread name, priority, stack usage, and current state.

§Returns

ThreadMetadata structure containing thread information

§Examples
use osal_rs::os::*;

let thread = Thread::new("worker", 1024, 3);
let meta = thread.get_metadata();

assert_eq!(meta.name.as_str(), "worker");
assert_eq!(meta.priority, 3);
Source

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

Gets a handle to the currently executing thread.

Returns a handle to the thread that is currently running. Useful for self-referential operations.

§Returns

Handle to the current thread

§Examples
use osal_rs::os::*;

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

let meta = current.get_metadata();
assert_eq!(meta.state, ThreadState::Running);
Source

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

Sends a notification to the thread.

Notifies the thread using the specified notification action. Task notifications are a lightweight signaling mechanism.

§Parameters
  • notification - The notification action to perform
§Returns
  • Ok(()) - Notification sent successfully
  • Err(Error) - Failed to send notification
§Examples
use osal_rs::os::*;
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};

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

let mut thread = Thread::new("worker", 1024, 1);
let worker = thread.spawn_simple(|| {
    let current = Thread::get_current();
    // Blocks until the notification below arrives.
    let value = current.wait_notification(0, 0, 1000).unwrap();
    RECEIVED.store(value, Ordering::SeqCst);
    Ok(Arc::new(()))
}).unwrap();

// Send a value. `ThreadNotification::SetBits` would signal an event
// instead, without disturbing the bits another event already set.
worker.notify(ThreadNotification::SetValueWithOverwrite(42)).unwrap();

worker.delete();
assert_eq!(RECEIVED.load(Ordering::SeqCst), 42);
Source

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

Sends a notification to the thread from ISR context.

ISR-safe version of notify(). Must only be called from interrupt context.

§Parameters
  • notification - The notification action to perform
  • higher_priority_task_woken - Set to non-zero if a context switch should occur
§Returns
  • Ok(()) - Notification sent successfully
  • Err(Error) - Failed to send notification
§Examples
use osal_rs::os::*;

// In interrupt handler
fn isr_handler(worker: &Thread) {
    let mut task_woken = 0;

    worker.notify_from_isr(
        ThreadNotification::Increment,
        &mut task_woken
    ).ok();

    System::yield_from_isr(task_woken);
}

let current = Thread::get_current();
isr_handler(&current);

// The notification is now pending on the notified thread.
assert_eq!(current.wait_notification(0, 0xFFFF_FFFF, 10).unwrap(), 1);
Source

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

Waits for a notification.

Blocks the calling thread until a notification is received or timeout occurs. Allows clearing specific bits on entry and/or exit.

§Parameters
  • bits_to_clear_on_entry - Bits to clear before waiting
  • bits_to_clear_on_exit - Bits to clear after receiving notification
  • timeout_ticks - Maximum ticks to wait (0 = no wait, MAX = wait forever)
§Returns
  • Ok(notification_value) - Notification received, returns the notification value
  • Err(Error::Timeout) - No notification received within timeout
  • Err(Error) - Other error occurred
§Note

This method does not use ToTick trait to maintain dynamic dispatch compatibility.

§Examples
use osal_rs::os::*;

let current = Thread::get_current();

// Nothing pending yet: this gives up once the timeout expires rather
// than blocking forever.
assert!(current.wait_notification(0, 0, 10).is_err());

// Wait for notification, clear all bits on exit
current.notify(ThreadNotification::SetValueWithOverwrite(7)).unwrap();
match current.wait_notification(0, 0xFFFFFFFF, 1000) {
    Ok(value) => assert_eq!(value, 7),
    Err(_) => panic!("timeout waiting for notification"),
}

// Wait for specific bits
let bits_of_interest = 0b0011;
current.notify(ThreadNotification::SetBits(bits_of_interest)).unwrap();
match current.wait_notification(0, bits_of_interest, 5000) {
    Ok(value) => assert_ne!(value & bits_of_interest, 0),
    Err(_) => panic!("timeout"),
}

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§