7 \defgroup pt Protothreads
9 Protothreads are a type of lightweight stackless threads designed for
10 severly memory constrained systems such as deeply embedded systems or
11 sensor network nodes. Protothreads provides linear code execution for
12 event-driven systems implemented in C. Protothreads can be used with
15 Protothreads are a extremely lightweight, stackless type of threads
16 that provides a blocking context on top of an event-driven system,
17 without the overhead of per-thread stacks. The purpose of protothreads
18 is to implement sequential flow of control without complex state
19 machines or full multi-threading. Protothreads provides conditional
20 blocking inside C functions.
22 The advantage of protothreads over a purely event-driven approach is
23 that protothreads provides a sequential code structure that allows for
24 blocking functions. In purely event-driven systems, blocking must be
25 implemented by manually breaking the function into two pieces - one
26 for the piece of code before the blocking call and one for the code
27 after the blocking call. This makes it hard to use control structures
28 such as if() conditionals and while() loops.
30 The advantage of protothreads over ordinary threads is that a
31 protothread do not require a separate stack. In memory constrained
32 systems, the overhead of allocating multiple stacks can consume large
33 amounts of the available memory. In contrast, each protothread only
34 requires between two and twelve bytes of state, depending on the
37 \note Because protothreads do not save the stack context across a
38 blocking call, <b>local variables are not preserved when the
39 protothread blocks</b>. This means that local variables should be used
40 with utmost care - <b>if in doubt, do not use local variables inside a
46 - No machine specific code - the protothreads library is pure C
48 - Does not use error-prone functions such as longjmp()
50 - Very small RAM overhead - only two bytes per protothread
52 - Can be used with or without an OS
54 - Provides blocking wait without full multi-threading or
57 Examples applications:
59 - Memory constrained systems
61 - Event-driven protocol stacks
63 - Deeply embedded systems
65 - Sensor network nodes
67 The protothreads API consists of four basic operations:
68 initialization: PT_INIT(), execution: PT_BEGIN(), conditional
69 blocking: PT_WAIT_UNTIL() and exit: PT_END(). On top of these, two
70 convenience functions are built: reversed condition blocking:
71 PT_WAIT_WHILE() and protothread blocking: PT_WAIT_THREAD().
73 \sa \ref pt "Protothreads API documentation"
75 The protothreads library is released under a BSD-style license that
76 allows for both non-commercial and commercial usage. The only
77 requirement is that credit is given.
79 \section authors Authors
81 The protothreads library was written by Adam Dunkels <adam@sics.se>
82 with support from Oliver Schmidt <ol.sc@web.de>.
84 \section pt-desc Protothreads
86 Protothreads are a extremely lightweight, stackless threads that
87 provides a blocking context on top of an event-driven system, without
88 the overhead of per-thread stacks. The purpose of protothreads is to
89 implement sequential flow of control without using complex state
90 machines or full multi-threading. Protothreads provides conditional
91 blocking inside a C function.
93 In memory constrained systems, such as deeply embedded systems,
94 traditional multi-threading may have a too large memory overhead. In
95 traditional multi-threading, each thread requires its own stack, that
96 typically is over-provisioned. The stacks may use large parts of the
99 The main advantage of protothreads over ordinary threads is that
100 protothreads are very lightweight: a protothread does not require its
101 own stack. Rather, all protothreads run on the same stack and context
102 switching is done by stack rewinding. This is advantageous in memory
103 constrained systems, where a stack for a thread might use a large part
104 of the available memory. A protothread only requires only two bytes of
105 memory per protothread. Moreover, protothreads are implemented in pure
106 C and do not require any machine-specific assembler code.
108 A protothread runs within a single C function and cannot span over
109 other functions. A protothread may call normal C functions, but cannot
110 block inside a called function. Blocking inside nested function calls
111 is instead made by spawning a separate protothread for each
112 potentially blocking function. The advantage of this approach is that
113 blocking is explicit: the programmer knows exactly which functions
114 that block that which functions the never blocks.
116 Protothreads are similar to asymmetric co-routines. The main
117 difference is that co-routines uses a separate stack for each
118 co-routine, whereas protothreads are stackless. The most similar
119 mechanism to protothreads are Python generators. These are also
120 stackless constructs, but have a different purpose. Protothreads
121 provides blocking contexts inside a C function, whereas Python
122 generators provide multiple exit points from a generator function.
124 \section pt-autovars Local variables
127 Because protothreads do not save the stack context across a blocking
128 call, local variables are not preserved when the protothread
129 blocks. This means that local variables should be used with utmost
130 care - if in doubt, do not use local variables inside a protothread!
132 \section pt-scheduling Scheduling
134 A protothread is driven by repeated calls to the function in which the
135 protothread is running. Each time the function is called, the
136 protothread will run until it blocks or exits. Thus the scheduling of
137 protothreads is done by the application that uses protothreads.
139 \section pt-impl Implementation
141 Protothreads are implemented using \ref lc "local continuations". A
142 local continuation represents the current state of execution at a
143 particular place in the program, but does not provide any call history
144 or local variables. A local continuation can be set in a specific
145 function to capture the state of the function. After a local
146 continuation has been set can be resumed in order to restore the state
147 of the function at the point where the local continuation was set.
150 Local continuations can be implemented in a variety of ways:
152 -# by using machine specific assembler code,
153 -# by using standard C constructs, or
154 -# by using compiler extensions.
156 The first way works by saving and restoring the processor state,
157 except for stack pointers, and requires between 16 and 32 bytes of
158 memory per protothread. The exact amount of memory required depends on
161 The standard C implementation requires only two bytes of state per
162 protothread and utilizes the C switch() statement in a non-obvious way
163 that is similar to Duff's device. This implementation does, however,
164 impose a slight restriction to the code that uses protothreads in that
165 the code cannot use switch() statements itself.
167 Certain compilers has C extensions that can be used to implement
168 protothreads. GCC supports label pointers that can be used for this
169 purpose. With this implementation, protothreads require 4 bytes of RAM