Skip to main content

Semaphore

Struct Semaphore 

Source
pub struct Semaphore(/* private fields */);
Expand description

Semaphore types for signaling and resource management. A counting semaphore for resource management and signaling.

Semaphores maintain a count that can be incremented (signaled) and decremented (waited). They are useful for:

  • Resource counting (e.g., managing a pool of N resources)
  • Event signaling between threads or from ISRs
  • Producer-consumer synchronization

§Examples

§Basic binary semaphore (mutex alternative)

use osal_rs::os::{Semaphore, SemaphoreFn};
use core::time::Duration;
 
// Create a binary semaphore (max_count = 1)
let sem = Semaphore::new(1, 1).unwrap();
 
// Wait (take) the semaphore
if sem.wait(Duration::from_millis(100)).into() {
    // Critical section
    println!("Acquired semaphore");
     
    // Signal (give) the semaphore
    sem.signal();
}

§Resource pool management

use osal_rs::os::{Semaphore, SemaphoreFn, Thread};
use alloc::sync::Arc;
use core::time::Duration;
 
// Create semaphore for 5 resources
let resources = Arc::new(Semaphore::new(5, 5).unwrap());
 
let sem_clone = resources.clone();
let worker = Thread::new("worker", 2048, 5, move || {
    loop {
        // Wait for an available resource
        if sem_clone.wait(Duration::from_secs(1)).into() {
            println!("Resource acquired");
             
            // Use resource...
            Duration::from_millis(500).sleep();
             
            // Release resource
            sem_clone.signal();
        }
    }
}).unwrap();

§Event signaling from ISR

use osal_rs::os::{Semaphore, SemaphoreFn};
use alloc::sync::Arc;
 
let event_sem = Arc::new(Semaphore::new(1, 0).unwrap());  // Initially unavailable
let sem_clone = event_sem.clone();
 
// In interrupt handler:
// sem_clone.signal_from_isr();  // Signal event occurred
 
// In thread:
if event_sem.wait(1000).into() {
    println!("Event received!");
}

§Counting events

use osal_rs::os::{Semaphore, SemaphoreFn};
use core::time::Duration;
 
// Create semaphore with max_count=10, initially empty
let counter = Semaphore::new(10, 0).unwrap();
 
// Signal 3 times
counter.signal();
counter.signal();
counter.signal();
 
// Process 3 events
for _ in 0..3 {
    if counter.wait(Duration::from_millis(10)).into() {
        println!("Processing event");
    }
}

Implementations§

Source§

impl Semaphore

Source

pub fn new(max_count: UBaseType, initial_count: UBaseType) -> Result<Self>

Creates a new counting semaphore.

§Parameters
  • max_count - Maximum count value the semaphore can reach
  • initial_count - Initial count value
§Returns
  • Ok(Semaphore) - Semaphore created successfully
  • Err(Error::OutOfMemory) - Failed to allocate semaphore
§Examples
use osal_rs::os::{Semaphore, SemaphoreFn};
 
// Binary semaphore
let binary_sem = Semaphore::new(1, 1).unwrap();
 
// Counting semaphore for 5 resources
let counting_sem = Semaphore::new(5, 5).unwrap();
Source

pub fn new_with_count(initial_count: UBaseType) -> Result<Self>

Creates a counting semaphore with maximum possible count.

Sets max_count to UBaseType::MAX.

§Parameters
  • initial_count - Initial count value
§Returns
  • Ok(Semaphore) - Semaphore created successfully
  • Err(Error::OutOfMemory) - Failed to allocate
§Examples
use osal_rs::os::{Semaphore, SemaphoreFn};
 
let sem = Semaphore::new_with_count(0).unwrap();

Trait Implementations§

Source§

impl Debug for Semaphore

Formats the semaphore for debugging purposes.

Source§

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

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

impl Deref for Semaphore

Allows dereferencing to the underlying FreeRTOS semaphore handle.

Source§

type Target = *const c_void

The resulting type after dereferencing.
Source§

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

Dereferences the value.
Source§

impl Display for Semaphore

Formats the semaphore for display purposes.

Source§

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

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

impl Drop for Semaphore

Automatically deletes the semaphore when it goes out of scope.

This ensures proper cleanup of FreeRTOS resources.

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Semaphore for Semaphore

Source§

fn wait(&self, ticks_to_wait: impl ToTick) -> OsalRsBool

Waits to acquire the semaphore (decrements count).

Blocks until semaphore is available or timeout expires.

§Parameters
  • ticks_to_wait - Maximum time to wait (supports Duration via ToTick)
§Returns
  • OsalRsBool::True - Semaphore acquired
  • OsalRsBool::False - Timeout or error
§Examples
use osal_rs::os::{Semaphore, SemaphoreFn};
use core::time::Duration;
 
let sem = Semaphore::new(1, 1).unwrap();
if sem.wait(Duration::from_millis(100)).into() {
    // Critical section
    sem.signal();
}
Source§

fn wait_from_isr(&self) -> OsalRsBool

Waits to acquire the semaphore from ISR context (non-blocking).

§Returns
  • OsalRsBool::True - Semaphore acquired
  • OsalRsBool::False - Semaphore not available
§Examples
// In ISR:
if sem.wait_from_isr().into() {
    // Handle event
}
Source§

fn signal(&self) -> OsalRsBool

Signals (releases) the semaphore (increments count).

§Returns
  • OsalRsBool::True - Semaphore signaled successfully
  • OsalRsBool::False - Error (e.g., count already at maximum)
§Examples
use osal_rs::os::{Semaphore, SemaphoreFn};
 
let sem = Semaphore::new(1, 0).unwrap();
sem.signal();  // Make semaphore available
Source§

fn signal_from_isr(&self) -> OsalRsBool

Signals the semaphore from ISR context.

Automatically yields to higher priority tasks if needed.

§Returns
  • OsalRsBool::True - Semaphore signaled successfully
  • OsalRsBool::False - Error
§Examples
// In ISR:
sem.signal_from_isr();
Source§

fn delete(&mut self)

Deletes the semaphore and frees its resources.

After calling this, the semaphore handle is set to null and should not be used.

§Safety

Ensure no threads are waiting on this semaphore before deleting it.

§Examples
use osal_rs::os::{Semaphore, SemaphoreFn};
 
let mut sem = Semaphore::new(1, 1).unwrap();
// Use the semaphore...
sem.delete();
Source§

impl Send for Semaphore

Source§

impl Sync for Semaphore

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> 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> 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.