]> git.sur5r.net Git - freertos/blob - Demo/Common/ethernet/FreeTCPIP/net/pt.h
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / Common / ethernet / FreeTCPIP / net / pt.h
1 /*\r
2  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\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
16  *\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
27  * SUCH DAMAGE.\r
28  *\r
29  * This file is part of the uIP TCP/IP stack\r
30  *\r
31  * Author: Adam Dunkels <adam@sics.se>\r
32  *\r
33  * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $\r
34  */\r
35 \r
36 /**\r
37  * \addtogroup pt\r
38  * @{\r
39  */\r
40 \r
41 /**\r
42  * \file\r
43  * Protothreads implementation.\r
44  * \author\r
45  * Adam Dunkels <adam@sics.se>\r
46  *\r
47  */\r
48 \r
49 #ifndef __PT_H__\r
50 #define __PT_H__\r
51 \r
52 #include "lc.h"\r
53 \r
54 struct pt {\r
55   lc_t lc;\r
56 };\r
57 \r
58 #define PT_WAITING 0\r
59 #define PT_EXITED  1\r
60 #define PT_ENDED   2\r
61 #define PT_YIELDED 3\r
62 \r
63 /**\r
64  * \name Initialization\r
65  * @{\r
66  */\r
67 \r
68 /**\r
69  * Initialize a protothread.\r
70  *\r
71  * Initializes a protothread. Initialization must be done prior to\r
72  * starting to execute the protothread.\r
73  *\r
74  * \param pt A pointer to the protothread control structure.\r
75  *\r
76  * \sa PT_SPAWN()\r
77  *\r
78  * \hideinitializer\r
79  */\r
80 #define PT_INIT(pt)   LC_INIT((pt)->lc)\r
81 \r
82 /** @} */\r
83 \r
84 /**\r
85  * \name Declaration and definition\r
86  * @{\r
87  */\r
88 \r
89 /**\r
90  * Declaration of a protothread.\r
91  *\r
92  * This macro is used to declare a protothread. All protothreads must\r
93  * be declared with this macro.\r
94  *\r
95  * \param name_args The name and arguments of the C function\r
96  * implementing the protothread.\r
97  *\r
98  * \hideinitializer\r
99  */\r
100 #define PT_THREAD(name_args) char name_args\r
101 \r
102 /**\r
103  * Declare the start of a protothread inside the C function\r
104  * implementing the protothread.\r
105  *\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
110  *\r
111  * \param pt A pointer to the protothread control structure.\r
112  *\r
113  * \hideinitializer\r
114  */\r
115 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)\r
116 \r
117 /**\r
118  * Declare the end of a protothread.\r
119  *\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
122  *\r
123  * \param pt A pointer to the protothread control structure.\r
124  *\r
125  * \hideinitializer\r
126  */\r
127 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \\r
128                    PT_INIT(pt); return PT_ENDED; }\r
129 \r
130 /** @} */\r
131 \r
132 /**\r
133  * \name Blocked wait\r
134  * @{\r
135  */\r
136 \r
137 /**\r
138  * Block and wait until condition is true.\r
139  *\r
140  * This macro blocks the protothread until the specified condition is\r
141  * true.\r
142  *\r
143  * \param pt A pointer to the protothread control structure.\r
144  * \param condition The condition.\r
145  *\r
146  * \hideinitializer\r
147  */\r
148 #define PT_WAIT_UNTIL(pt, condition)            \\r
149   do {                                          \\r
150     LC_SET((pt)->lc);                           \\r
151     if(!(condition)) {                          \\r
152       return PT_WAITING;                        \\r
153     }                                           \\r
154   } while(0)\r
155 \r
156 /**\r
157  * Block and wait while condition is true.\r
158  *\r
159  * This function blocks and waits while condition is true. See\r
160  * PT_WAIT_UNTIL().\r
161  *\r
162  * \param pt A pointer to the protothread control structure.\r
163  * \param cond The condition.\r
164  *\r
165  * \hideinitializer\r
166  */\r
167 #define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))\r
168 \r
169 /** @} */\r
170 \r
171 /**\r
172  * \name Hierarchical protothreads\r
173  * @{\r
174  */\r
175 \r
176 /**\r
177  * Block and wait until a child protothread completes.\r
178  *\r
179  * This macro schedules a child protothread. The current protothread\r
180  * will block until the child protothread completes.\r
181  *\r
182  * \note The child protothread must be manually initialized with the\r
183  * PT_INIT() function before this function is used.\r
184  *\r
185  * \param pt A pointer to the protothread control structure.\r
186  * \param thread The child protothread with arguments\r
187  *\r
188  * \sa PT_SPAWN()\r
189  *\r
190  * \hideinitializer\r
191  */\r
192 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))\r
193 \r
194 /**\r
195  * Spawn a child protothread and wait until it exits.\r
196  *\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
199  *\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
203  *\r
204  * \hideinitializer\r
205  */\r
206 #define PT_SPAWN(pt, child, thread)             \\r
207   do {                                          \\r
208     PT_INIT((child));                           \\r
209     PT_WAIT_THREAD((pt), (thread));             \\r
210   } while(0)\r
211 \r
212 /** @} */\r
213 \r
214 /**\r
215  * \name Exiting and restarting\r
216  * @{\r
217  */\r
218 \r
219 /**\r
220  * Restart the protothread.\r
221  *\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
224  *\r
225  * \param pt A pointer to the protothread control structure.\r
226  *\r
227  * \hideinitializer\r
228  */\r
229 #define PT_RESTART(pt)                          \\r
230   do {                                          \\r
231     PT_INIT(pt);                                \\r
232     return PT_WAITING;                  \\r
233   } while(0)\r
234 \r
235 /**\r
236  * Exit the protothread.\r
237  *\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
241  *\r
242  * \param pt A pointer to the protothread control structure.\r
243  *\r
244  * \hideinitializer\r
245  */\r
246 #define PT_EXIT(pt)                             \\r
247   do {                                          \\r
248     PT_INIT(pt);                                \\r
249     return PT_EXITED;                   \\r
250   } while(0)\r
251 \r
252 /** @} */\r
253 \r
254 /**\r
255  * \name Calling a protothread\r
256  * @{\r
257  */\r
258 \r
259 /**\r
260  * Schedule a protothread.\r
261  *\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
265  *\r
266  * \param f The call to the C function implementing the protothread to\r
267  * be scheduled\r
268  *\r
269  * \hideinitializer\r
270  */\r
271 #define PT_SCHEDULE(f) ((f) == PT_WAITING)\r
272 \r
273 /** @} */\r
274 \r
275 /**\r
276  * \name Yielding from a protothread\r
277  * @{\r
278  */\r
279 \r
280 /**\r
281  * Yield from the current protothread.\r
282  *\r
283  * This function will yield the protothread, thereby allowing other\r
284  * processing to take place in the system.\r
285  *\r
286  * \param pt A pointer to the protothread control structure.\r
287  *\r
288  * \hideinitializer\r
289  */\r
290 #define PT_YIELD(pt)                            \\r
291   do {                                          \\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
296     }                                           \\r
297   } while(0)\r
298 \r
299 /**\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
303  *\r
304  *             This function will yield the protothread, until the\r
305  *             specified condition evaluates to true.\r
306  *\r
307  *\r
308  * \hideinitializer\r
309  */\r
310 #define PT_YIELD_UNTIL(pt, cond)                \\r
311   do {                                          \\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
316     }                                           \\r
317   } while(0)\r
318 \r
319 /** @} */\r
320 \r
321 #endif /* __PT_H__ */\r
322 \r
323 /** @} */\r