librfn
An ad-hoc utility library
|
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_t * | fibre_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) |
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.
#define FIBRE_EVENTQ_VAR_INIT | ( | fn, | |
basep, | |||
base_len, | |||
msg_len | |||
) |
Static initializer for a fibre and eventq descriptor.
#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.
#define FIBRE_VAR_INIT | ( | fn | ) | { (fn), 0, 0, 0, LIST_NODE_VAR_INIT } |
#define PT_BEGIN_FIBRE | ( | f | ) | PT_BEGIN(&((f)->priv)) |
Fibre aware alternative to PT_BEGIN().
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().
enum fibre_state_t |
void* fibre_eventq_claim | ( | fibre_eventq_t * | evtq | ) |
bool fibre_eventq_empty | ( | fibre_eventq_t * | evtq | ) |
void fibre_eventq_init | ( | fibre_eventq_t * | evtq, |
fibre_entrypoint_t * | fn, | ||
void * | basep, | ||
size_t | base_len, | ||
size_t | msg_len | ||
) |
void* fibre_eventq_receive | ( | fibre_eventq_t * | evtq | ) |
void fibre_eventq_release | ( | fibre_eventq_t * | evtq, |
void * | evtp | ||
) |
bool fibre_eventq_send | ( | fibre_eventq_t * | evtq, |
void * | evtp | ||
) |
void fibre_init | ( | fibre_t * | f, |
fibre_entrypoint_t * | fn | ||
) |
bool fibre_kill | ( | fibre_t * | f | ) |
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().
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.
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).
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.
time | current time in cyclic 32-bit time (e.g. 0 is one tick after 0xffffffff) |
fibre_t* fibre_self | ( | void | ) |
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.