Skip to content

File syn_pt.h

FileList > pt > syn_pt.h

Go to the source code of this file

Protothreads — stackless cooperative coroutines for C. More...

  • #include "../common/syn_compiler.h"
  • #include "../common/syn_defs.h"

Classes

Type Name
struct SYN_PT
Protothread control block.

Public Types

Type Name
enum SYN_PT_Status
Return value from a protothread function.

Macros

Type Name
define PT_BEGIN (pt) /* multi line expression */
Open a protothread body. Must be the first statement in the protothread function, before any PT_* operations.
define PT_BLOCK_EVENT (pt, task, grp, mask) /* multi line expression */
Block until ANY bit in mask is set in the event group.
define PT_DEFER (pt, task) /* multi line expression */
Defer to all ready tasks, regardless of priority.
define PT_DELAY_MS (pt, target, ms) /* multi line expression */
Non-blocking delay for ms milliseconds.
define PT_END (pt) /* multi line expression */
Close a protothread body. Returns PT_EXITED and resets the continuation so the thread can be restarted if desired.
define PT_EXIT (pt) /* multi line expression */
Terminate the protothread immediately.
define PT_INIT (pt) ((pt)->lc = 0)
Initialize (or reset) a protothread so it starts from the top.
define PT_IS_IDLE (pt) ((pt)->lc == 0)
define PT_IS_RUNNING (pt) ((pt)->lc != 0)
define PT_RESTART (pt) /* multi line expression */
Reset the protothread and restart from PT_BEGIN on next call.
define PT_SPAWN (pt, child, func) /* multi line expression */
Spawn a child protothread and block until it exits.
define PT_TASK_DELAY_MS (pt, task, ms) [**PT\_DELAY\_MS**](syn__pt_8h.md#define-pt_delay_ms)(pt, &(task)->delay\_until, ms)
Convenience form for use with the scheduler's SYN_Task .
define PT_WAIT_UNTIL (pt, cond) /* multi line expression */
Block until cond evaluates to true.
define PT_WAIT_WHILE (pt, cond) [**PT\_WAIT\_UNTIL**](syn__pt_8h.md#define-pt_wait_until)(pt, !(cond))
Block while cond is true. Dual of PT_WAIT_UNTIL.
define PT_YIELD (pt) /* multi line expression */
Yield control unconditionally. The protothread will resume at this point on the next call.
define PT_YIELD_UNTIL (pt, cond) /* multi line expression */
Yield while cond is true.

Detailed Description

Protothreads provide lightweight, cooperative multitasking without requiring a separate stack per thread. Each protothread is a normal C function that uses macros to save and restore its execution position via the switch/__LINE__ continuation trick (Duff's device).

A protothread costs 2 bytes of RAM (the continuation variable).

** **

  • You cannot use a bare switch statement inside a protothread body (use if/else if chains instead).
  • Local variables are NOT preserved across yield/wait points. Store persistent state in static variables, globals, or a struct passed via the task's user_data pointer.
  • A protothread must reside entirely within a single function.

** **

static SYN_PT pt;
PT_INIT(&pt);

while (1) {
    my_protothread(&pt);
    // ... poll other protothreads ...
}

** **

// See syn_sched.h for the full pattern.
static SYN_PT_Status my_task(SYN_PT *pt, SYN_Task *task) {
    PT_BEGIN(pt);
    // ...
    PT_END(pt);
}

Public Types Documentation

enum SYN_PT_Status

Return value from a protothread function.

enum SYN_PT_Status {
    PT_WAITING = 0,
    PT_YIELDED = 1,
    PT_EXITED = 2,
    PT_ENDED = 3
};


Macro Definition Documentation

define PT_BEGIN

Open a protothread body. Must be the first statement in the protothread function, before any PT_* operations.

#define PT_BEGIN (
    pt
) `/* multi line expression */`

Expands to the head of a switch statement that jumps to the last saved continuation point.


define PT_BLOCK_EVENT

Block until ANY bit in mask is set in the event group.

#define PT_BLOCK_EVENT (
    pt,
    task,
    grp,
    mask
) `/* multi line expression */`

Unlike PT_WAIT_EVENT (which polls every scheduler pass), this macro sets the task state to BLOCKED. The scheduler skips the task entirely until the event fires, saving CPU and enabling proper tickless sleep.

Matched flags are auto-cleared after the task resumes.

Note:

The clear runs after PT_YIELD returns (i.e. after the scheduler has already detected the flags during its scan), so it is safe for the scheduler to use the flags as a wakeup condition.

Parameters:

  • pt Protothread.
  • task Pointer to the SYN_Task struct.
  • grp Pointer to SYN_EventGroup.
  • mask Bitmask of event flags to wait for (any of them).

define PT_DEFER

Defer to all ready tasks, regardless of priority.

#define PT_DEFER (
    pt,
    task
) `/* multi line expression */`

Unlike PT_YIELD (which only round-robins among equal-priority tasks), this macro allows any lower-priority ready task to run before this task is scheduled again. The task is skipped for exactly one scheduler pass.

Use this when a high-priority task has no immediate work but doesn't want to commit to a timed delay.

Parameters:

  • pt Protothread.
  • task Pointer to the SYN_Task struct.

define PT_DELAY_MS

Non-blocking delay for ms milliseconds.

#define PT_DELAY_MS (
    pt,
    target,
    ms
) `/* multi line expression */`

Requires a uint32_t variable to store the deadline. When used with the scheduler, pass &(task)->delay_until. For standalone use, pass any persistent uint32_t *.

Parameters:

  • pt Protothread.
  • target Pointer to a uint32_t that will hold the deadline tick.
  • ms Delay duration in milliseconds.

define PT_END

Close a protothread body. Returns PT_EXITED and resets the continuation so the thread can be restarted if desired.

#define PT_END (
    pt
) `/* multi line expression */`


define PT_EXIT

Terminate the protothread immediately.

#define PT_EXIT (
    pt
) `/* multi line expression */`


define PT_INIT

Initialize (or reset) a protothread so it starts from the top.

#define PT_INIT (
    pt
) `((pt)->lc = 0)`


define PT_IS_IDLE

#define PT_IS_IDLE (
    pt
) `((pt)->lc == 0)`

Check if a protothread has not yet started or has been reset.


define PT_IS_RUNNING

#define PT_IS_RUNNING (
    pt
) `((pt)->lc != 0)`

Check if a protothread is still running (has not exited).


define PT_RESTART

Reset the protothread and restart from PT_BEGIN on next call.

#define PT_RESTART (
    pt
) `/* multi line expression */`


define PT_SPAWN

Spawn a child protothread and block until it exits.

#define PT_SPAWN (
    pt,
    child,
    func
) `/* multi line expression */`

Parameters:

  • pt Parent protothread.
  • child Child protothread (SYN_PT struct).
  • func Expression that calls the child's function, e.g. child_func(&child_pt).

Usage:

static SYN_PT child_pt;
PT_SPAWN(pt, &child_pt, child_func(&child_pt));


define PT_TASK_DELAY_MS

Convenience form for use with the scheduler's SYN_Task .

#define PT_TASK_DELAY_MS (
    pt,
    task,
    ms
) `PT_DELAY_MS (pt, &(task)->delay_until, ms)`

Parameters:

  • pt Protothread.
  • task Pointer to the SYN_Task struct.
  • ms Delay duration in milliseconds.

define PT_WAIT_UNTIL

Block until cond evaluates to true.

#define PT_WAIT_UNTIL (
    pt,
    cond
) `/* multi line expression */`

Each time the protothread is polled and cond is false, it returns PT_WAITING and resumes at this point on the next call.


define PT_WAIT_WHILE

Block while cond is true. Dual of PT_WAIT_UNTIL.

#define PT_WAIT_WHILE (
    pt,
    cond
) `PT_WAIT_UNTIL (pt, !(cond))`


define PT_YIELD

Yield control unconditionally. The protothread will resume at this point on the next call.

#define PT_YIELD (
    pt
) `/* multi line expression */`


define PT_YIELD_UNTIL

Yield while cond is true.

#define PT_YIELD_UNTIL (
    pt,
    cond
) `/* multi line expression */`

Like PT_WAIT_WHILE, but returns PT_YIELDED instead of PT_WAITING, signaling the scheduler that this thread actively wants to run.



The documentation for this class was generated from the following file src/syntropic/pt/syn_pt.h