Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
pt.h
00001 /* 00002 * Copyright (c) 2004-2005, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 * Author: Adam Dunkels <adam@sics.se> 00032 * 00033 */ 00034 00035 /** 00036 * \addtogroup pt 00037 * @{ 00038 */ 00039 00040 /** 00041 * \file 00042 * Protothreads implementation. 00043 * \author 00044 * Adam Dunkels <adam@sics.se> 00045 * 00046 */ 00047 00048 #ifndef __PT_H__ 00049 #define __PT_H__ 00050 00051 #include "lc.h" 00052 00053 struct pt { 00054 lc_t lc; 00055 }; 00056 00057 #define PT_WAITING 0 00058 #define PT_YIELDED 1 00059 #define PT_EXITED 2 00060 #define PT_ENDED 3 00061 00062 /** 00063 * \name Initialization 00064 * @{ 00065 */ 00066 00067 /** 00068 * Initialize a protothread. 00069 * 00070 * Initializes a protothread. Initialization must be done prior to 00071 * starting to execute the protothread. 00072 * 00073 * \param pt A pointer to the protothread control structure. 00074 * 00075 * \sa PT_SPAWN() 00076 * 00077 * \hideinitializer 00078 */ 00079 #define PT_INIT(pt) LC_INIT((pt)->lc) 00080 00081 /** @} */ 00082 00083 /** 00084 * \name Declaration and definition 00085 * @{ 00086 */ 00087 00088 /** 00089 * Declaration of a protothread. 00090 * 00091 * This macro is used to declare a protothread. All protothreads must 00092 * be declared with this macro. 00093 * 00094 * \param name_args The name and arguments of the C function 00095 * implementing the protothread. 00096 * 00097 * \hideinitializer 00098 */ 00099 #define PT_THREAD(name_args) char name_args 00100 00101 /** 00102 * Declare the start of a protothread inside the C function 00103 * implementing the protothread. 00104 * 00105 * This macro is used to declare the starting point of a 00106 * protothread. It should be placed at the start of the function in 00107 * which the protothread runs. All C statements above the PT_BEGIN() 00108 * invokation will be executed each time the protothread is scheduled. 00109 * 00110 * \param pt A pointer to the protothread control structure. 00111 * 00112 * \hideinitializer 00113 */ 00114 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} LC_RESUME((pt)->lc) 00115 00116 /** 00117 * Declare the end of a protothread. 00118 * 00119 * This macro is used for declaring that a protothread ends. It must 00120 * always be used together with a matching PT_BEGIN() macro. 00121 * 00122 * \param pt A pointer to the protothread control structure. 00123 * 00124 * \hideinitializer 00125 */ 00126 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ 00127 PT_INIT(pt); return PT_ENDED; } 00128 00129 /** @} */ 00130 00131 /** 00132 * \name Blocked wait 00133 * @{ 00134 */ 00135 00136 /** 00137 * Block and wait until condition is true. 00138 * 00139 * This macro blocks the protothread until the specified condition is 00140 * true. 00141 * 00142 * \param pt A pointer to the protothread control structure. 00143 * \param condition The condition. 00144 * 00145 * \hideinitializer 00146 */ 00147 #define PT_WAIT_UNTIL(pt, condition) \ 00148 do { \ 00149 LC_SET((pt)->lc); \ 00150 if(!(condition)) { \ 00151 return PT_WAITING; \ 00152 } \ 00153 } while(0) 00154 00155 /** 00156 * Block and wait while condition is true. 00157 * 00158 * This function blocks and waits while condition is true. See 00159 * PT_WAIT_UNTIL(). 00160 * 00161 * \param pt A pointer to the protothread control structure. 00162 * \param cond The condition. 00163 * 00164 * \hideinitializer 00165 */ 00166 #define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) 00167 00168 /** @} */ 00169 00170 /** 00171 * \name Hierarchical protothreads 00172 * @{ 00173 */ 00174 00175 /** 00176 * Block and wait until a child protothread completes. 00177 * 00178 * This macro schedules a child protothread. The current protothread 00179 * will block until the child protothread completes. 00180 * 00181 * \note The child protothread must be manually initialized with the 00182 * PT_INIT() function before this function is used. 00183 * 00184 * \param pt A pointer to the protothread control structure. 00185 * \param thread The child protothread with arguments 00186 * 00187 * \sa PT_SPAWN() 00188 * 00189 * \hideinitializer 00190 */ 00191 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) 00192 00193 /** 00194 * Spawn a child protothread and wait until it exits. 00195 * 00196 * This macro spawns a child protothread and waits until it exits. The 00197 * macro can only be used within a protothread. 00198 * 00199 * \param pt A pointer to the protothread control structure. 00200 * \param child A pointer to the child protothread's control structure. 00201 * \param thread The child protothread with arguments 00202 * 00203 * \hideinitializer 00204 */ 00205 #define PT_SPAWN(pt, child, thread) \ 00206 do { \ 00207 PT_INIT((child)); \ 00208 PT_WAIT_THREAD((pt), (thread)); \ 00209 } while(0) 00210 00211 /** @} */ 00212 00213 /** 00214 * \name Exiting and restarting 00215 * @{ 00216 */ 00217 00218 /** 00219 * Restart the protothread. 00220 * 00221 * This macro will block and cause the running protothread to restart 00222 * its execution at the place of the PT_BEGIN() call. 00223 * 00224 * \param pt A pointer to the protothread control structure. 00225 * 00226 * \hideinitializer 00227 */ 00228 #define PT_RESTART(pt) \ 00229 do { \ 00230 PT_INIT(pt); \ 00231 return PT_WAITING; \ 00232 } while(0) 00233 00234 /** 00235 * Exit the protothread. 00236 * 00237 * This macro causes the protothread to exit. If the protothread was 00238 * spawned by another protothread, the parent protothread will become 00239 * unblocked and can continue to run. 00240 * 00241 * \param pt A pointer to the protothread control structure. 00242 * 00243 * \hideinitializer 00244 */ 00245 #define PT_EXIT(pt) \ 00246 do { \ 00247 PT_INIT(pt); \ 00248 return PT_EXITED; \ 00249 } while(0) 00250 00251 /** @} */ 00252 00253 /** 00254 * \name Calling a protothread 00255 * @{ 00256 */ 00257 00258 /** 00259 * Schedule a protothread. 00260 * 00261 * This function schedules a protothread. The return value of the 00262 * function is non-zero if the protothread is running or zero if the 00263 * protothread has exited. 00264 * 00265 * \param f The call to the C function implementing the protothread to 00266 * be scheduled 00267 * 00268 * \hideinitializer 00269 */ 00270 #define PT_SCHEDULE(f) ((f) < PT_EXITED) 00271 00272 /** @} */ 00273 00274 /** 00275 * \name Yielding from a protothread 00276 * @{ 00277 */ 00278 00279 /** 00280 * Yield from the current protothread. 00281 * 00282 * This function will yield the protothread, thereby allowing other 00283 * processing to take place in the system. 00284 * 00285 * \param pt A pointer to the protothread control structure. 00286 * 00287 * \hideinitializer 00288 */ 00289 #define PT_YIELD(pt) \ 00290 do { \ 00291 PT_YIELD_FLAG = 0; \ 00292 LC_SET((pt)->lc); \ 00293 if(PT_YIELD_FLAG == 0) { \ 00294 return PT_YIELDED; \ 00295 } \ 00296 } while(0) 00297 00298 /** 00299 * \brief Yield from the protothread until a condition occurs. 00300 * \param pt A pointer to the protothread control structure. 00301 * \param cond The condition. 00302 * 00303 * This function will yield the protothread, until the 00304 * specified condition evaluates to true. 00305 * 00306 * 00307 * \hideinitializer 00308 */ 00309 #define PT_YIELD_UNTIL(pt, cond) \ 00310 do { \ 00311 PT_YIELD_FLAG = 0; \ 00312 LC_SET((pt)->lc); \ 00313 if((PT_YIELD_FLAG == 0) || !(cond)) { \ 00314 return PT_YIELDED; \ 00315 } \ 00316 } while(0) 00317 00318 /** @} */ 00319 00320 #endif /* __PT_H__ */ 00321 00322 /** @} */
Generated on Tue Jul 12 2022 12:52:12 by
1.7.2