[][src]Trait sunrise_kernel::event::Waitable

pub trait Waitable: Debug + Send + Sync {
    fn is_signaled(&self) -> bool;
fn register(&self); }

A waitable item.

There are essentially two kinds of Waitables: user-signaled and IRQ-backed. IRQ-backed waitables are implemented by IRQEvent, while user-signaled events are implemented by ReadableEvent.

It is possible that a raw waitable is not flexible enough though. For instance, if we want to wait for 1 second, it might be necessary to wait on the timer event multiple times. To do this, it is possible to implement our own Waitable, that defers register to the underlying IRQEvent, but adds additional logic to is_signaled. For example:

use sunrise_kernel::event::{IRQEvent, Waitable};
use core::sync::atomic::{AtomicUsize, Ordering};
struct WaitFor5Ticks(IRQEvent, AtomicUsize);
impl Waitable for WaitFor5Ticks {
    fn is_signaled(&self) -> bool {
        self.1.compare_and_swap(0, 5, Ordering::SeqCst);
        if self.0.is_signaled() {
            if self.1.fetch_sub(1) == 0 {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    fn register(&self) {
        self.0.register()
    }
}

Required methods

fn is_signaled(&self) -> bool

Checks whether the Waitable was signalled.

If it returns false, the register function will be called again, in order to get notified of the next wakeup.

This will likely require to change state - and yet it takes self by value. the reason for this is that it's possible for multiple threads, and potentially multiple CPUs, to wait on the same Waitable. Think of servers: you might want to wait for multiple threads for the arrival of a new socket. When this happens, only a single thread should return true. Make extra sure your Atomic operations are written properly!

You'll probably want to check out AtomicUsize::fetch_update to make sure your atomic update loops are correct.

fn register(&self)

Register the waitable with the scheduler.

This should ensure that when the event is (or is likely to be) triggered, the scheduler puts the Process back in the running Vec. Most implementors will want to defer this to an IRQEvent. For instance:

#use sunrise_kernel::event::{IRQEvent, Waitable};
#struct Wait(IRQEvent);
#impl Waitable for WaitFor5Ticks {
#fn is_signaled(&self) -> bool {
#self.0.is_signaled()
#}
fn register(&self) {
    self.0.register()
}
#}
Loading content...

Implementations on Foreign Types

impl Waitable for Weak<ThreadStruct>[src]

If this waitable is signaled, this means the thread has exited.

impl Waitable for Arc<ProcessStruct>[src]

Loading content...

Implementors

impl Waitable for IRQEvent[src]

impl Waitable for ReadableEvent[src]

impl Waitable for ServerPort[src]

impl Waitable for ServerSession[src]

impl Waitable for IRQTimer[src]

Loading content...