]> git.zerfleddert.de Git - fnordlicht-mini/blob - firmware/common/pt/pt.h
92856cbcd5fa769932939673af6d1fa0f6de4354
[fnordlicht-mini] / firmware / common / pt / pt.h
1 /*
2 * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 * Author: Adam Dunkels <adam@sics.se>
32 *
33 * $Id: pt.h,v 1.7 2006/10/02 07:52:56 adam Exp $
34 */
35
36 /**
37 * \addtogroup pt
38 * @{
39 */
40
41 /**
42 * \file
43 * Protothreads implementation.
44 * \author
45 * Adam Dunkels <adam@sics.se>
46 *
47 */
48
49 #ifndef __PT_H__
50 #define __PT_H__
51
52 #include "lc.h"
53
54 struct pt {
55 lc_t lc;
56 };
57
58 #define PT_WAITING 0
59 #define PT_YIELDED 1
60 #define PT_EXITED 2
61 #define PT_ENDED 3
62
63 /**
64 * \name Initialization
65 * @{
66 */
67
68 /**
69 * Initialize a protothread.
70 *
71 * Initializes a protothread. Initialization must be done prior to
72 * starting to execute the protothread.
73 *
74 * \param pt A pointer to the protothread control structure.
75 *
76 * \sa PT_SPAWN()
77 *
78 * \hideinitializer
79 */
80 #define PT_INIT(pt) LC_INIT((pt)->lc)
81
82 /** @} */
83
84 /**
85 * \name Declaration and definition
86 * @{
87 */
88
89 /**
90 * Declaration of a protothread.
91 *
92 * This macro is used to declare a protothread. All protothreads must
93 * be declared with this macro.
94 *
95 * \param name_args The name and arguments of the C function
96 * implementing the protothread.
97 *
98 * \hideinitializer
99 */
100 #define PT_THREAD(name_args) char name_args
101
102 /**
103 * Declare the start of a protothread inside the C function
104 * implementing the protothread.
105 *
106 * This macro is used to declare the starting point of a
107 * protothread. It should be placed at the start of the function in
108 * which the protothread runs. All C statements above the PT_BEGIN()
109 * invokation will be executed each time the protothread is scheduled.
110 *
111 * \param pt A pointer to the protothread control structure.
112 *
113 * \hideinitializer
114 */
115 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
116
117 /**
118 * Declare the end of a protothread.
119 *
120 * This macro is used for declaring that a protothread ends. It must
121 * always be used together with a matching PT_BEGIN() macro.
122 *
123 * \param pt A pointer to the protothread control structure.
124 *
125 * \hideinitializer
126 */
127 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
128 PT_INIT(pt); return PT_ENDED; }
129
130 /** @} */
131
132 /**
133 * \name Blocked wait
134 * @{
135 */
136
137 /**
138 * Block and wait until condition is true.
139 *
140 * This macro blocks the protothread until the specified condition is
141 * true.
142 *
143 * \param pt A pointer to the protothread control structure.
144 * \param condition The condition.
145 *
146 * \hideinitializer
147 */
148 #define PT_WAIT_UNTIL(pt, condition) \
149 do { \
150 LC_SET((pt)->lc); \
151 if(!(condition)) { \
152 return PT_WAITING; \
153 } \
154 } while(0)
155
156 /**
157 * Block and wait while condition is true.
158 *
159 * This function blocks and waits while condition is true. See
160 * PT_WAIT_UNTIL().
161 *
162 * \param pt A pointer to the protothread control structure.
163 * \param cond The condition.
164 *
165 * \hideinitializer
166 */
167 #define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
168
169 /** @} */
170
171 /**
172 * \name Hierarchical protothreads
173 * @{
174 */
175
176 /**
177 * Block and wait until a child protothread completes.
178 *
179 * This macro schedules a child protothread. The current protothread
180 * will block until the child protothread completes.
181 *
182 * \note The child protothread must be manually initialized with the
183 * PT_INIT() function before this function is used.
184 *
185 * \param pt A pointer to the protothread control structure.
186 * \param thread The child protothread with arguments
187 *
188 * \sa PT_SPAWN()
189 *
190 * \hideinitializer
191 */
192 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
193
194 /**
195 * Spawn a child protothread and wait until it exits.
196 *
197 * This macro spawns a child protothread and waits until it exits. The
198 * macro can only be used within a protothread.
199 *
200 * \param pt A pointer to the protothread control structure.
201 * \param child A pointer to the child protothread's control structure.
202 * \param thread The child protothread with arguments
203 *
204 * \hideinitializer
205 */
206 #define PT_SPAWN(pt, child, thread) \
207 do { \
208 PT_INIT((child)); \
209 PT_WAIT_THREAD((pt), (thread)); \
210 } while(0)
211
212 /** @} */
213
214 /**
215 * \name Exiting and restarting
216 * @{
217 */
218
219 /**
220 * Restart the protothread.
221 *
222 * This macro will block and cause the running protothread to restart
223 * its execution at the place of the PT_BEGIN() call.
224 *
225 * \param pt A pointer to the protothread control structure.
226 *
227 * \hideinitializer
228 */
229 #define PT_RESTART(pt) \
230 do { \
231 PT_INIT(pt); \
232 return PT_WAITING; \
233 } while(0)
234
235 /**
236 * Exit the protothread.
237 *
238 * This macro causes the protothread to exit. If the protothread was
239 * spawned by another protothread, the parent protothread will become
240 * unblocked and can continue to run.
241 *
242 * \param pt A pointer to the protothread control structure.
243 *
244 * \hideinitializer
245 */
246 #define PT_EXIT(pt) \
247 do { \
248 PT_INIT(pt); \
249 return PT_EXITED; \
250 } while(0)
251
252 /** @} */
253
254 /**
255 * \name Calling a protothread
256 * @{
257 */
258
259 /**
260 * Schedule a protothread.
261 *
262 * This function shedules a protothread. The return value of the
263 * function is non-zero if the protothread is running or zero if the
264 * protothread has exited.
265 *
266 * \param f The call to the C function implementing the protothread to
267 * be scheduled
268 *
269 * \hideinitializer
270 */
271 #define PT_SCHEDULE(f) ((f) < PT_EXITED)
272
273 /** @} */
274
275 /**
276 * \name Yielding from a protothread
277 * @{
278 */
279
280 /**
281 * Yield from the current protothread.
282 *
283 * This function will yield the protothread, thereby allowing other
284 * processing to take place in the system.
285 *
286 * \param pt A pointer to the protothread control structure.
287 *
288 * \hideinitializer
289 */
290 #define PT_YIELD(pt) \
291 do { \
292 PT_YIELD_FLAG = 0; \
293 LC_SET((pt)->lc); \
294 if(PT_YIELD_FLAG == 0) { \
295 return PT_YIELDED; \
296 } \
297 } while(0)
298
299 /**
300 * \brief Yield from the protothread until a condition occurs.
301 * \param pt A pointer to the protothread control structure.
302 * \param cond The condition.
303 *
304 * This function will yield the protothread, until the
305 * specified condition evaluates to true.
306 *
307 *
308 * \hideinitializer
309 */
310 #define PT_YIELD_UNTIL(pt, cond) \
311 do { \
312 PT_YIELD_FLAG = 0; \
313 LC_SET((pt)->lc); \
314 if((PT_YIELD_FLAG == 0) || !(cond)) { \
315 return PT_YIELDED; \
316 } \
317 } while(0)
318
319 /** @} */
320
321 #endif /* __PT_H__ */
322
323 /** @} */
Impressum, Datenschutz