librfn
An ad-hoc utility library
Data Structures | Macros | Typedefs | Enumerations | Functions
Fibre

Lightweight run-to-completion task scheduler supporting protothreads. More...

Data Structures

struct  fibre
 Fibre descriptor. More...
 
struct  fibre_eventq
 Fibre and eventq descriptor. More...
 

Macros

#define FIBRE_UNBOUNDED_SLEEP   ((uint32_t) 0x7fffffff)
 An approximation of infinitely far in the future. More...
 
#define FIBRE_VAR_INIT(fn)   { (fn), 0, 0, 0, LIST_NODE_VAR_INIT }
 Static initializer for a fibre descriptor. More...
 
#define FIBRE_EVENTQ_VAR_INIT(fn, basep, base_len, msg_len)
 Static initializer for a fibre and eventq descriptor. More...
 
#define PT_BEGIN_FIBRE(f)   PT_BEGIN(&((f)->priv))
 Fibre aware alternative to PT_BEGIN(). More...
 

Typedefs

typedef int fibre_entrypoint_t(struct fibre *)
 
typedef struct fibre fibre_t
 Fibre descriptor. More...
 
typedef struct fibre_eventq fibre_eventq_t
 Fibre and eventq descriptor. More...
 

Enumerations

enum  fibre_state_t {
  FIBRE_STATE_YIELDED = PT_YIELDED, FIBRE_STATE_WAITING = PT_WAITING, FIBRE_STATE_EXITED = PT_EXITED, FIBRE_STATE_RUNNING,
  FIBRE_STATE_QUEUED = 0x10, FIBRE_STATE_TIMER_WAITING = FIBRE_STATE_WAITING | FIBRE_STATE_QUEUED, FIBRE_STATE_RUNNABLE = FIBRE_STATE_RUNNING | FIBRE_STATE_QUEUED
}
 

Functions

fibre_tfibre_self (void)
 Returns the currently active fibre descriptor. More...
 
uint32_t fibre_scheduler_next (uint32_t time)
 Schedule the next fibre. More...
 
void fibre_init (fibre_t *f, fibre_entrypoint_t *fn)
 Dynamic initializer for a fibre descriptor. More...
 
void fibre_run (fibre_t *f)
 
bool fibre_run_atomic (fibre_t *f)
 
bool fibre_kill (fibre_t *f)
 
bool fibre_timeout (uint32_t duetime)
 
void fibre_eventq_init (fibre_eventq_t *evtq, fibre_entrypoint_t *fn, void *basep, size_t base_len, size_t msg_len)
 Dynamic initializer for a fibre and eventq descriptor. More...
 
void * fibre_eventq_claim (fibre_eventq_t *evtq)
 Request memory resources to send an event to a fibre. More...
 
bool fibre_eventq_send (fibre_eventq_t *evtq, void *evtp)
 Send an event to a fibre. More...
 
bool fibre_eventq_empty (fibre_eventq_t *evtq)
 Return true if the fibre's event queue is empty. More...
 
void * fibre_eventq_receive (fibre_eventq_t *evtq)
 Recevied a message previously send to the fibre. More...
 
void fibre_eventq_release (fibre_eventq_t *evtq, void *evtp)
 Release a message previously received by a fibre. More...
 
void fibre_scheduler_main_loop (void)
 

Detailed Description

Lightweight run-to-completion task scheduler supporting protothreads.

The fibre scheduler is an extremely lightweight run-to-completion task scheduler supporting protothreads. In addition to timer and run queue management it also provides support for per-fibre event queues.

Macro Definition Documentation

#define FIBRE_EVENTQ_VAR_INIT (   fn,
  basep,
  base_len,
  msg_len 
)
Value:
{ \
.fibre = FIBRE_VAR_INIT(fn), \
.eventq = MESSAGEQ_VAR_INIT(basep, base_len, msg_len) \
}
#define FIBRE_VAR_INIT(fn)
Static initializer for a fibre descriptor.
Definition: fibre.h:75
#define MESSAGEQ_VAR_INIT(basep, base_len, msg_len)
Definition: messageq.h:54

Static initializer for a fibre and eventq descriptor.

Definition at line 94 of file fibre.h.

#define FIBRE_UNBOUNDED_SLEEP   ((uint32_t) 0x7fffffff)

An approximation of infinitely far in the future.

This is the largest possible value that can be added to the current time and still yeild a value in the future (a larger value will cause the time to wrap around to be in the past).

With the typical 1MHz clock provided by time_now(), it actually represents a little over three and a half minutes.

Definition at line 56 of file fibre.h.

#define FIBRE_VAR_INIT (   fn)    { (fn), 0, 0, 0, LIST_NODE_VAR_INIT }

Static initializer for a fibre descriptor.

Definition at line 75 of file fibre.h.

#define PT_BEGIN_FIBRE (   f)    PT_BEGIN(&((f)->priv))

Fibre aware alternative to PT_BEGIN().

Definition at line 103 of file fibre.h.

Typedef Documentation

typedef int fibre_entrypoint_t(struct fibre *)

Definition at line 59 of file fibre.h.

typedef struct fibre_eventq fibre_eventq_t

Fibre and eventq descriptor.

This descriptor is a fibre and messag queue bound together so that events can be passed to the fibre.

Allows the fibre to be automatically scheduled if events are passed using fibre_eventq_send().

typedef struct fibre fibre_t

Fibre descriptor.

Enumeration Type Documentation

Enumerator
FIBRE_STATE_YIELDED 
FIBRE_STATE_WAITING 
FIBRE_STATE_EXITED 
FIBRE_STATE_RUNNING 
FIBRE_STATE_QUEUED 
FIBRE_STATE_TIMER_WAITING 
FIBRE_STATE_RUNNABLE 

Definition at line 34 of file fibre.h.

Function Documentation

void* fibre_eventq_claim ( fibre_eventq_t evtq)

Request memory resources to send an event to a fibre.

Note
If the fibre's event queue is full the kernel will automtically be tainted (the 'E' bit will be set).

Definition at line 226 of file fibre.c.

bool fibre_eventq_empty ( fibre_eventq_t evtq)

Return true if the fibre's event queue is empty.

Definition at line 240 of file fibre.c.

void fibre_eventq_init ( fibre_eventq_t evtq,
fibre_entrypoint_t fn,
void *  basep,
size_t  base_len,
size_t  msg_len 
)

Dynamic initializer for a fibre and eventq descriptor.

Definition at line 219 of file fibre.c.

void* fibre_eventq_receive ( fibre_eventq_t evtq)

Recevied a message previously send to the fibre.

This function can be used by a fibre to receive an event.

Warning
This function should only be called by the fibre bound to the event queue and must not be called by an interrupt service routine.

Definition at line 245 of file fibre.c.

void fibre_eventq_release ( fibre_eventq_t evtq,
void *  evtp 
)

Release a message previously received by a fibre.

Definition at line 250 of file fibre.c.

bool fibre_eventq_send ( fibre_eventq_t evtq,
void *  evtp 
)

Send an event to a fibre.

If the fibre is not already runnable then it will be added to the run queue.

Definition at line 234 of file fibre.c.

void fibre_init ( fibre_t f,
fibre_entrypoint_t fn 
)

Dynamic initializer for a fibre descriptor.

Definition at line 164 of file fibre.c.

bool fibre_kill ( fibre_t f)

Remove a fibre from the run queue.

Definition at line 196 of file fibre.c.

void fibre_run ( fibre_t f)

Make a fibre runnable.

When a fibre is made runnable it will be appended to the run queue and will, eventually be executed during a call to fibre_scheduler_next().

Warning
Do not call this function from an interrupt service routine, use fibre_run_atomic() instead.

Definition at line 173 of file fibre.c.

bool fibre_run_atomic ( fibre_t f)

Make a fibre runnable using only atomic operations.

This function behaves similarly fibre_run(). It is less efficient than the alternative but can be used from any calling context, including from an interrupt service routine.

Definition at line 183 of file fibre.c.

void fibre_scheduler_main_loop ( void  )

Enter the scheduler main loop.

This function will dispatch threads when they become runnable and may attempt to conserve power by going idle in some implementation defined manner.

An implementation of this function must be provided for each execution environment. librfn only comes with an implementation for a small subset of environments and may have to be provided by the library user. POSIX environments are, however, already supported to allow the demonstation programs to work.

Definition at line 17 of file fibre_default.c.

uint32_t fibre_scheduler_next ( uint32_t  time)

Schedule the next fibre.

This is the heart of the fibre system. Any fibre whose due time is before time will be made runnable and the fibre at the head of the run queue will execute. When that fibre completes the scheduler returns the time of the next wakeup (which may be in the past if the run queue contains active tasks).

Note
fibre_self(), when called after fibre_scheduler_next() has executed, returns the fibre that was most recently scheduled. This can be used to implement task accounting and to debug scheduling delays.

The return value provides the time at which the next task must be scheduled this allows low power modes to implemented by programming a wakeup timer and sleeping until it fires.

Warning
It is possible for an interrupt service routine to make a fibre runnable between this function returning and entering a low power state. On ARM architecture the WFE instruction avoids potential races by managing an event flag which is set by reception of interrupt. On hardware without this feature additional work is required to safely enter low power states.
Parameters
timecurrent time in cyclic 32-bit time (e.g. 0 is one tick after 0xffffffff)
Returns
time at which the next task must be scheduled

Definition at line 134 of file fibre.c.

fibre_t* fibre_self ( void  )

Returns the currently active fibre descriptor.

Definition at line 129 of file fibre.c.

bool fibre_timeout ( uint32_t  duetime)

Sleep until a timeout is reached.

Combining this function with PT_WAIT_UNTIL() allows a fibre to sleep. It will be automatically added to the run queue when the specified time is reached.

Definition at line 208 of file fibre.c.