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