Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / geekos / include / uip / 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 uIP TCP/IP stack
30  *
31  * Author: Adam Dunkels <adam@sics.se>
32  *
33  * $Id: pt.h,v 1.2 2008/08/06 23:40:07 andrewlxia 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 <uip/lc.h>
53
54 typedef struct pt {
55   lc_t lc;
56 }pt;
57
58 #define PT_WAITING 0
59 #define PT_EXITED  1
60 #define PT_ENDED   2
61 #define PT_YIELDED 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_WAITING)
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 /** @} */