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 * $Id: pt.h,v 1.7 2006/10/02 07:52:56 adam Exp $ 00034 */ 00035 00036 /** 00037 * \addtogroup pt 00038 * @{ 00039 */ 00040 00041 /** 00042 * \file 00043 * Protothreads implementation. 00044 * \author 00045 * Adam Dunkels <adam@sics.se> 00046 * 00047 */ 00048 00049 #ifndef __PT_H__ 00050 #define __PT_H__ 00051 00052 #include "lc.h" 00053 00054 struct pt { 00055 lc_t lc; 00056 }; 00057 00058 #define PT_WAITING 0 00059 #define PT_YIELDED 1 00060 #define PT_EXITED 2 00061 #define PT_ENDED 3 00062 00063 /** 00064 * \name Initialization 00065 * @{ 00066 */ 00067 00068 /** 00069 * Initialize a protothread. 00070 * 00071 * Initializes a protothread. Initialization must be done prior to 00072 * starting to execute the protothread. 00073 * 00074 * \param pt A pointer to the protothread control structure. 00075 * 00076 * \sa PT_SPAWN() 00077 * 00078 * \hideinitializer 00079 */ 00080 #define PT_INIT(pt) LC_INIT((pt)->lc) 00081 00082 /** @} */ 00083 00084 /** 00085 * \name Declaration and definition 00086 * @{ 00087 */ 00088 00089 /** 00090 * Declaration of a protothread. 00091 * 00092 * This macro is used to declare a protothread. All protothreads must 00093 * be declared with this macro. 00094 * 00095 * \param name_args The name and arguments of the C function 00096 * implementing the protothread. 00097 * 00098 * \hideinitializer 00099 */ 00100 #define PT_THREAD(name_args) char name_args 00101 00102 /** 00103 * Declare the start of a protothread inside the C function 00104 * implementing the protothread. 00105 * 00106 * This macro is used to declare the starting point of a 00107 * protothread. It should be placed at the start of the function in 00108 * which the protothread runs. All C statements above the PT_BEGIN() 00109 * invokation will be executed each time the protothread is scheduled. 00110 * 00111 * \param pt A pointer to the protothread control structure. 00112 * 00113 * \hideinitializer 00114 */ 00115 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) 00116 00117 /** 00118 * Declare the end of a protothread. 00119 * 00120 * This macro is used for declaring that a protothread ends. It must 00121 * always be used together with a matching PT_BEGIN() macro. 00122 * 00123 * \param pt A pointer to the protothread control structure. 00124 * 00125 * \hideinitializer 00126 */ 00127 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ 00128 PT_INIT(pt); return PT_ENDED; } 00129 00130 /** @} */ 00131 00132 /** 00133 * \name Blocked wait 00134 * @{ 00135 */ 00136 00137 /** 00138 * Block and wait until condition is true. 00139 * 00140 * This macro blocks the protothread until the specified condition is 00141 * true. 00142 * 00143 * \param pt A pointer to the protothread control structure. 00144 * \param condition The condition. 00145 * 00146 * \hideinitializer 00147 */ 00148 #define PT_WAIT_UNTIL(pt, condition) \ 00149 do { \ 00150 LC_SET((pt)->lc); \ 00151 if(!(condition)) { \ 00152 return PT_WAITING; \ 00153 } \ 00154 } while(0) 00155 00156 /** 00157 * Block and wait while condition is true. 00158 * 00159 * This function blocks and waits while condition is true. See 00160 * PT_WAIT_UNTIL(). 00161 * 00162 * \param pt A pointer to the protothread control structure. 00163 * \param cond The condition. 00164 * 00165 * \hideinitializer 00166 */ 00167 #define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) 00168 00169 /** @} */ 00170 00171 /** 00172 * \name Hierarchical protothreads 00173 * @{ 00174 */ 00175 00176 /** 00177 * Block and wait until a child protothread completes. 00178 * 00179 * This macro schedules a child protothread. The current protothread 00180 * will block until the child protothread completes. 00181 * 00182 * \note The child protothread must be manually initialized with the 00183 * PT_INIT() function before this function is used. 00184 * 00185 * \param pt A pointer to the protothread control structure. 00186 * \param thread The child protothread with arguments 00187 * 00188 * \sa PT_SPAWN() 00189 * 00190 * \hideinitializer 00191 */ 00192 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) 00193 00194 /** 00195 * Spawn a child protothread and wait until it exits. 00196 * 00197 * This macro spawns a child protothread and waits until it exits. The 00198 * macro can only be used within a protothread. 00199 * 00200 * \param pt A pointer to the protothread control structure. 00201 * \param child A pointer to the child protothread's control structure. 00202 * \param thread The child protothread with arguments 00203 * 00204 * \hideinitializer 00205 */ 00206 #define PT_SPAWN(pt, child, thread) \ 00207 do { \ 00208 PT_INIT((child)); \ 00209 PT_WAIT_THREAD((pt), (thread)); \ 00210 } while(0) 00211 00212 /** @} */ 00213 00214 /** 00215 * \name Exiting and restarting 00216 * @{ 00217 */ 00218 00219 /** 00220 * Restart the protothread. 00221 * 00222 * This macro will block and cause the running protothread to restart 00223 * its execution at the place of the PT_BEGIN() call. 00224 * 00225 * \param pt A pointer to the protothread control structure. 00226 * 00227 * \hideinitializer 00228 */ 00229 #define PT_RESTART(pt) \ 00230 do { \ 00231 PT_INIT(pt); \ 00232 return PT_WAITING; \ 00233 } while(0) 00234 00235 /** 00236 * Exit the protothread. 00237 * 00238 * This macro causes the protothread to exit. If the protothread was 00239 * spawned by another protothread, the parent protothread will become 00240 * unblocked and can continue to run. 00241 * 00242 * \param pt A pointer to the protothread control structure. 00243 * 00244 * \hideinitializer 00245 */ 00246 #define PT_EXIT(pt) \ 00247 do { \ 00248 PT_INIT(pt); \ 00249 return PT_EXITED; \ 00250 } while(0) 00251 00252 /** @} */ 00253 00254 /** 00255 * \name Calling a protothread 00256 * @{ 00257 */ 00258 00259 /** 00260 * Schedule a protothread. 00261 * 00262 * This function shedules a protothread. The return value of the 00263 * function is non-zero if the protothread is running or zero if the 00264 * protothread has exited. 00265 * 00266 * \param f The call to the C function implementing the protothread to 00267 * be scheduled 00268 * 00269 * \hideinitializer 00270 */ 00271 #define PT_SCHEDULE(f) ((f) < PT_EXITED) 00272 00273 /** @} */ 00274 00275 /** 00276 * \name Yielding from a protothread 00277 * @{ 00278 */ 00279 00280 /** 00281 * Yield from the current protothread. 00282 * 00283 * This function will yield the protothread, thereby allowing other 00284 * processing to take place in the system. 00285 * 00286 * \param pt A pointer to the protothread control structure. 00287 * 00288 * \hideinitializer 00289 */ 00290 #define PT_YIELD(pt) \ 00291 do { \ 00292 PT_YIELD_FLAG = 0; \ 00293 LC_SET((pt)->lc); \ 00294 if(PT_YIELD_FLAG == 0) { \ 00295 return PT_YIELDED; \ 00296 } \ 00297 } while(0) 00298 00299 /** 00300 * \brief Yield from the protothread until a condition occurs. 00301 * \param pt A pointer to the protothread control structure. 00302 * \param cond The condition. 00303 * 00304 * This function will yield the protothread, until the 00305 * specified condition evaluates to true. 00306 * 00307 * 00308 * \hideinitializer 00309 */ 00310 #define PT_YIELD_UNTIL(pt, cond) \ 00311 do { \ 00312 PT_YIELD_FLAG = 0; \ 00313 LC_SET((pt)->lc); \ 00314 if((PT_YIELD_FLAG == 0) || !(cond)) { \ 00315 return PT_YIELDED; \ 00316 } \ 00317 } while(0) 00318 00319 /** @} */ 00320 00321 #endif /* __PT_H__ */ 00322 00323 /** @} */
Generated on Wed Jul 13 2022 11:59:11 by
1.7.2