2 * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions
\r
8 * 1. Redistributions of source code must retain the above copyright
\r
9 * notice, this list of conditions and the following disclaimer.
\r
10 * 2. Redistributions in binary form must reproduce the above copyright
\r
11 * notice, this list of conditions and the following disclaimer in the
\r
12 * documentation and/or other materials provided with the distribution.
\r
13 * 3. Neither the name of the Institute nor the names of its contributors
\r
14 * may be used to endorse or promote products derived from this software
\r
15 * without specific prior written permission.
\r
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
\r
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
\r
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\r
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\r
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\r
29 * This file is part of the uIP TCP/IP stack
\r
31 * Author: Adam Dunkels <adam@sics.se>
\r
33 * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
\r
43 * Protothreads implementation.
\r
45 * Adam Dunkels <adam@sics.se>
\r
58 #define PT_WAITING 0
\r
61 #define PT_YIELDED 3
\r
64 * \name Initialization
\r
69 * Initialize a protothread.
\r
71 * Initializes a protothread. Initialization must be done prior to
\r
72 * starting to execute the protothread.
\r
74 * \param pt A pointer to the protothread control structure.
\r
80 #define PT_INIT(pt) LC_INIT((pt)->lc)
\r
85 * \name Declaration and definition
\r
90 * Declaration of a protothread.
\r
92 * This macro is used to declare a protothread. All protothreads must
\r
93 * be declared with this macro.
\r
95 * \param name_args The name and arguments of the C function
\r
96 * implementing the protothread.
\r
100 #define PT_THREAD(name_args) char name_args
\r
103 * Declare the start of a protothread inside the C function
\r
104 * implementing the protothread.
\r
106 * This macro is used to declare the starting point of a
\r
107 * protothread. It should be placed at the start of the function in
\r
108 * which the protothread runs. All C statements above the PT_BEGIN()
\r
109 * invokation will be executed each time the protothread is scheduled.
\r
111 * \param pt A pointer to the protothread control structure.
\r
115 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
\r
118 * Declare the end of a protothread.
\r
120 * This macro is used for declaring that a protothread ends. It must
\r
121 * always be used together with a matching PT_BEGIN() macro.
\r
123 * \param pt A pointer to the protothread control structure.
\r
127 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
\r
128 PT_INIT(pt); return PT_ENDED; }
\r
133 * \name Blocked wait
\r
138 * Block and wait until condition is true.
\r
140 * This macro blocks the protothread until the specified condition is
\r
143 * \param pt A pointer to the protothread control structure.
\r
144 * \param condition The condition.
\r
148 #define PT_WAIT_UNTIL(pt, condition) \
\r
150 LC_SET((pt)->lc); \
\r
151 if(!(condition)) { \
\r
152 return PT_WAITING; \
\r
157 * Block and wait while condition is true.
\r
159 * This function blocks and waits while condition is true. See
\r
162 * \param pt A pointer to the protothread control structure.
\r
163 * \param cond The condition.
\r
167 #define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
\r
172 * \name Hierarchical protothreads
\r
177 * Block and wait until a child protothread completes.
\r
179 * This macro schedules a child protothread. The current protothread
\r
180 * will block until the child protothread completes.
\r
182 * \note The child protothread must be manually initialized with the
\r
183 * PT_INIT() function before this function is used.
\r
185 * \param pt A pointer to the protothread control structure.
\r
186 * \param thread The child protothread with arguments
\r
192 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
\r
195 * Spawn a child protothread and wait until it exits.
\r
197 * This macro spawns a child protothread and waits until it exits. The
\r
198 * macro can only be used within a protothread.
\r
200 * \param pt A pointer to the protothread control structure.
\r
201 * \param child A pointer to the child protothread's control structure.
\r
202 * \param thread The child protothread with arguments
\r
206 #define PT_SPAWN(pt, child, thread) \
\r
208 PT_INIT((child)); \
\r
209 PT_WAIT_THREAD((pt), (thread)); \
\r
215 * \name Exiting and restarting
\r
220 * Restart the protothread.
\r
222 * This macro will block and cause the running protothread to restart
\r
223 * its execution at the place of the PT_BEGIN() call.
\r
225 * \param pt A pointer to the protothread control structure.
\r
229 #define PT_RESTART(pt) \
\r
232 return PT_WAITING; \
\r
236 * Exit the protothread.
\r
238 * This macro causes the protothread to exit. If the protothread was
\r
239 * spawned by another protothread, the parent protothread will become
\r
240 * unblocked and can continue to run.
\r
242 * \param pt A pointer to the protothread control structure.
\r
246 #define PT_EXIT(pt) \
\r
249 return PT_EXITED; \
\r
255 * \name Calling a protothread
\r
260 * Schedule a protothread.
\r
262 * This function shedules a protothread. The return value of the
\r
263 * function is non-zero if the protothread is running or zero if the
\r
264 * protothread has exited.
\r
266 * \param f The call to the C function implementing the protothread to
\r
271 #define PT_SCHEDULE(f) ((f) == PT_WAITING)
\r
276 * \name Yielding from a protothread
\r
281 * Yield from the current protothread.
\r
283 * This function will yield the protothread, thereby allowing other
\r
284 * processing to take place in the system.
\r
286 * \param pt A pointer to the protothread control structure.
\r
290 #define PT_YIELD(pt) \
\r
292 PT_YIELD_FLAG = 0; \
\r
293 LC_SET((pt)->lc); \
\r
294 if(PT_YIELD_FLAG == 0) { \
\r
295 return PT_YIELDED; \
\r
300 * \brief Yield from the protothread until a condition occurs.
\r
301 * \param pt A pointer to the protothread control structure.
\r
302 * \param cond The condition.
\r
304 * This function will yield the protothread, until the
\r
305 * specified condition evaluates to true.
\r
310 #define PT_YIELD_UNTIL(pt, cond) \
\r
312 PT_YIELD_FLAG = 0; \
\r
313 LC_SET((pt)->lc); \
\r
314 if((PT_YIELD_FLAG == 0) || !(cond)) { \
\r
315 return PT_YIELDED; \
\r
321 #endif /* __PT_H__ */
\r