librfn
An ad-hoc utility library
Macros | Typedefs | Enumerations
Protothreads

Cooperative multi-tasking without context switching. More...

Macros

#define PT_INIT(pt)
 
#define PT_BEGIN(pt)
 
#define PT_END()
 
#define PT_WAIT()
 
#define PT_WAIT_UNTIL(c)
 
#define PT_YIELD()
 
#define PT_EXIT()   return PT_EXITED
 
#define PT_EXIT_ON(x)
 Conditional exit. More...
 
#define PT_SPAWN(child, thread)
 Call a child thread. More...
 
#define PT_CALL(child, thread)
 Call a child thread synchronously. More...
 

Typedefs

typedef uint16_t pt_t
 

Enumerations

enum  pt_state_t { PT_YIELDED, PT_WAITING, PT_EXITED }
 

Detailed Description

Cooperative multi-tasking without context switching.

Protothreads rely on the normal function call mechanism to switch contexts, however macros provides by the protothread implementation result in execution continuing from the point the thread yielded the processor.

This very simple example does not require a scheduler. Instead the blink function can be called from a polling loop (or systick interrupt) along with all system activity.

int blink_led(void) {
static pt_state_t ps;
static uint64_t t;
PT_INIT(&ps);
t = time64_now();
while (true) {
led_toggle();
t += 250000;
}
PT_END();
}
Note
In dynamic environments where the blink_led() routine is used to implement more than one thread then the pt_state_t and the time, t, must be passed in as an argument (usually as part of a context structure) rather than being static variables.

Like all protothread implementations this work is inspired by the paper "Protothreads: Simplifying Event-Driven Programming of Memory-Constrained Embedded Systems" by Dunkels et al.

This implementation uses a similar interface as that proposed by Dunkels et al but with sufficient changes to make them incompatible:

  1. Stronger distinction between yielding and waiting. This allows a scheduler to handle the cases differently. The fibre scheduler included in this library observes this distinction. We also eliminate the local continuation macros concept allowing an implementation of PT_YIELD() with no state variable.
  2. PT_INIT() saves the protothread pointer to simplify the usage of the other macros.
  3. The use of the provided pt_t type is optional. Any integer type large enough not to overflow when LINE is assigned to it is sufficient.

Macro Definition Documentation

#define PT_BEGIN (   pt)
Value:
{ \
pt_t *missing_PT_BEGIN = pt; \
(void) missing_PT_BEGIN; \
switch (*missing_PT_BEGIN) { \
case 0:
uint16_t pt_t
Definition: protothreads.h:86

Definition at line 93 of file protothreads.h.

#define PT_CALL (   child,
  thread 
)
Value:
do { \
PT_INIT(child); \
while (PT_EXITED != (thread)) \
; \
} while (0)
#define PT_INIT(pt)
Definition: protothreads.h:88

Call a child thread synchronously.

Run a protothread without ever yielding. This macro is intended to allow protothread library code to be executed in a non-protothreaded environment (for example during initialization routines).

Definition at line 167 of file protothreads.h.

#define PT_END ( )
Value:
break; \
default: \
assert(0); \
} \
} \
return PT_EXITED

Definition at line 100 of file protothreads.h.

#define PT_EXIT ( )    return PT_EXITED

Definition at line 132 of file protothreads.h.

#define PT_EXIT_ON (   x)
Value:
do { \
if (x) \
return PT_EXITED; \
} while (0)

Conditional exit.

Mostly used to simplify error paths.

Definition at line 140 of file protothreads.h.

#define PT_INIT (   pt)
Value:
do { \
*(pt) = 0; \
} while (0)

Definition at line 88 of file protothreads.h.

#define PT_SPAWN (   child,
  thread 
)
Value:
do { \
pt_state_t ptres; \
PT_INIT(child); \
*missing_PT_BEGIN = __LINE__; \
case __LINE__: \
ptres = (thread); \
if (ptres != PT_EXITED) \
return ptres; \
} while (0)
pt_state_t
Definition: protothreads.h:80
#define PT_INIT(pt)
Definition: protothreads.h:88

Call a child thread.

Definition at line 149 of file protothreads.h.

#define PT_WAIT ( )
Value:
do { \
*missing_PT_BEGIN = __LINE__; \
return PT_WAITING; \
case __LINE__: \
; \
} while (0)

Definition at line 108 of file protothreads.h.

#define PT_WAIT_UNTIL (   c)
Value:
do { \
*missing_PT_BEGIN = __LINE__; \
case __LINE__: \
if (!(c)) \
return PT_WAITING; \
} while (0)
struct charlie c

Definition at line 116 of file protothreads.h.

#define PT_YIELD ( )
Value:
do { \
*missing_PT_BEGIN = __LINE__; \
return PT_YIELDED; \
case __LINE__: \
; \
} while (0)

Definition at line 124 of file protothreads.h.

Typedef Documentation

typedef uint16_t pt_t

Definition at line 86 of file protothreads.h.

Enumeration Type Documentation

enum pt_state_t
Enumerator
PT_YIELDED 
PT_WAITING 
PT_EXITED 

Definition at line 80 of file protothreads.h.