XIAOHUI TAO / Mbed 2 deprecated hw2_protothread
Committer:
taoxh
Date:
Tue Nov 30 23:53:06 2010 +0000
Revision:
0:ee91220d7bea
HW2 PROTOTHREAD

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taoxh 0:ee91220d7bea 1 /*
taoxh 0:ee91220d7bea 2 * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
taoxh 0:ee91220d7bea 3 * All rights reserved.
taoxh 0:ee91220d7bea 4 *
taoxh 0:ee91220d7bea 5 * Redistribution and use in source and binary forms, with or without
taoxh 0:ee91220d7bea 6 * modification, are permitted provided that the following conditions
taoxh 0:ee91220d7bea 7 * are met:
taoxh 0:ee91220d7bea 8 * 1. Redistributions of source code must retain the above copyright
taoxh 0:ee91220d7bea 9 * notice, this list of conditions and the following disclaimer.
taoxh 0:ee91220d7bea 10 * 2. Redistributions in binary form must reproduce the above copyright
taoxh 0:ee91220d7bea 11 * notice, this list of conditions and the following disclaimer in the
taoxh 0:ee91220d7bea 12 * documentation and/or other materials provided with the distribution.
taoxh 0:ee91220d7bea 13 * 3. Neither the name of the Institute nor the names of its contributors
taoxh 0:ee91220d7bea 14 * may be used to endorse or promote products derived from this software
taoxh 0:ee91220d7bea 15 * without specific prior written permission.
taoxh 0:ee91220d7bea 16 *
taoxh 0:ee91220d7bea 17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
taoxh 0:ee91220d7bea 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
taoxh 0:ee91220d7bea 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
taoxh 0:ee91220d7bea 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
taoxh 0:ee91220d7bea 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
taoxh 0:ee91220d7bea 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
taoxh 0:ee91220d7bea 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
taoxh 0:ee91220d7bea 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
taoxh 0:ee91220d7bea 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
taoxh 0:ee91220d7bea 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
taoxh 0:ee91220d7bea 27 * SUCH DAMAGE.
taoxh 0:ee91220d7bea 28 *
taoxh 0:ee91220d7bea 29 * This file is part of the Contiki operating system.
taoxh 0:ee91220d7bea 30 *
taoxh 0:ee91220d7bea 31 * Author: Adam Dunkels <adam@sics.se>
taoxh 0:ee91220d7bea 32 *
taoxh 0:ee91220d7bea 33 * $Id: pt.h,v 1.7 2006/10/02 07:52:56 adam Exp $
taoxh 0:ee91220d7bea 34 */
taoxh 0:ee91220d7bea 35
taoxh 0:ee91220d7bea 36 /**
taoxh 0:ee91220d7bea 37 * \addtogroup pt
taoxh 0:ee91220d7bea 38 * @{
taoxh 0:ee91220d7bea 39 */
taoxh 0:ee91220d7bea 40
taoxh 0:ee91220d7bea 41 /**
taoxh 0:ee91220d7bea 42 * \file
taoxh 0:ee91220d7bea 43 * Protothreads implementation.
taoxh 0:ee91220d7bea 44 * \author
taoxh 0:ee91220d7bea 45 * Adam Dunkels <adam@sics.se>
taoxh 0:ee91220d7bea 46 *
taoxh 0:ee91220d7bea 47 */
taoxh 0:ee91220d7bea 48
taoxh 0:ee91220d7bea 49 #ifndef __PT_H__
taoxh 0:ee91220d7bea 50 #define __PT_H__
taoxh 0:ee91220d7bea 51
taoxh 0:ee91220d7bea 52 #include "lc.h"
taoxh 0:ee91220d7bea 53
taoxh 0:ee91220d7bea 54 struct pt {
taoxh 0:ee91220d7bea 55 lc_t lc;
taoxh 0:ee91220d7bea 56 };
taoxh 0:ee91220d7bea 57
taoxh 0:ee91220d7bea 58 #define PT_WAITING 0
taoxh 0:ee91220d7bea 59 #define PT_YIELDED 1
taoxh 0:ee91220d7bea 60 #define PT_EXITED 2
taoxh 0:ee91220d7bea 61 #define PT_ENDED 3
taoxh 0:ee91220d7bea 62
taoxh 0:ee91220d7bea 63 /**
taoxh 0:ee91220d7bea 64 * \name Initialization
taoxh 0:ee91220d7bea 65 * @{
taoxh 0:ee91220d7bea 66 */
taoxh 0:ee91220d7bea 67
taoxh 0:ee91220d7bea 68 /**
taoxh 0:ee91220d7bea 69 * Initialize a protothread.
taoxh 0:ee91220d7bea 70 *
taoxh 0:ee91220d7bea 71 * Initializes a protothread. Initialization must be done prior to
taoxh 0:ee91220d7bea 72 * starting to execute the protothread.
taoxh 0:ee91220d7bea 73 *
taoxh 0:ee91220d7bea 74 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 75 *
taoxh 0:ee91220d7bea 76 * \sa PT_SPAWN()
taoxh 0:ee91220d7bea 77 *
taoxh 0:ee91220d7bea 78 * \hideinitializer
taoxh 0:ee91220d7bea 79 */
taoxh 0:ee91220d7bea 80 #define PT_INIT(pt) LC_INIT((pt)->lc)
taoxh 0:ee91220d7bea 81
taoxh 0:ee91220d7bea 82 /** @} */
taoxh 0:ee91220d7bea 83
taoxh 0:ee91220d7bea 84 /**
taoxh 0:ee91220d7bea 85 * \name Declaration and definition
taoxh 0:ee91220d7bea 86 * @{
taoxh 0:ee91220d7bea 87 */
taoxh 0:ee91220d7bea 88
taoxh 0:ee91220d7bea 89 /**
taoxh 0:ee91220d7bea 90 * Declaration of a protothread.
taoxh 0:ee91220d7bea 91 *
taoxh 0:ee91220d7bea 92 * This macro is used to declare a protothread. All protothreads must
taoxh 0:ee91220d7bea 93 * be declared with this macro.
taoxh 0:ee91220d7bea 94 *
taoxh 0:ee91220d7bea 95 * \param name_args The name and arguments of the C function
taoxh 0:ee91220d7bea 96 * implementing the protothread.
taoxh 0:ee91220d7bea 97 *
taoxh 0:ee91220d7bea 98 * \hideinitializer
taoxh 0:ee91220d7bea 99 */
taoxh 0:ee91220d7bea 100 #define PT_THREAD(name_args) char name_args
taoxh 0:ee91220d7bea 101
taoxh 0:ee91220d7bea 102 /**
taoxh 0:ee91220d7bea 103 * Declare the start of a protothread inside the C function
taoxh 0:ee91220d7bea 104 * implementing the protothread.
taoxh 0:ee91220d7bea 105 *
taoxh 0:ee91220d7bea 106 * This macro is used to declare the starting point of a
taoxh 0:ee91220d7bea 107 * protothread. It should be placed at the start of the function in
taoxh 0:ee91220d7bea 108 * which the protothread runs. All C statements above the PT_BEGIN()
taoxh 0:ee91220d7bea 109 * invokation will be executed each time the protothread is scheduled.
taoxh 0:ee91220d7bea 110 *
taoxh 0:ee91220d7bea 111 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 112 *
taoxh 0:ee91220d7bea 113 * \hideinitializer
taoxh 0:ee91220d7bea 114 */
taoxh 0:ee91220d7bea 115 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
taoxh 0:ee91220d7bea 116
taoxh 0:ee91220d7bea 117 /**
taoxh 0:ee91220d7bea 118 * Declare the end of a protothread.
taoxh 0:ee91220d7bea 119 *
taoxh 0:ee91220d7bea 120 * This macro is used for declaring that a protothread ends. It must
taoxh 0:ee91220d7bea 121 * always be used together with a matching PT_BEGIN() macro.
taoxh 0:ee91220d7bea 122 *
taoxh 0:ee91220d7bea 123 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 124 *
taoxh 0:ee91220d7bea 125 * \hideinitializer
taoxh 0:ee91220d7bea 126 */
taoxh 0:ee91220d7bea 127 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
taoxh 0:ee91220d7bea 128 PT_INIT(pt); return PT_ENDED; }
taoxh 0:ee91220d7bea 129
taoxh 0:ee91220d7bea 130 /** @} */
taoxh 0:ee91220d7bea 131
taoxh 0:ee91220d7bea 132 /**
taoxh 0:ee91220d7bea 133 * \name Blocked wait
taoxh 0:ee91220d7bea 134 * @{
taoxh 0:ee91220d7bea 135 */
taoxh 0:ee91220d7bea 136
taoxh 0:ee91220d7bea 137 /**
taoxh 0:ee91220d7bea 138 * Block and wait until condition is true.
taoxh 0:ee91220d7bea 139 *
taoxh 0:ee91220d7bea 140 * This macro blocks the protothread until the specified condition is
taoxh 0:ee91220d7bea 141 * true.
taoxh 0:ee91220d7bea 142 *
taoxh 0:ee91220d7bea 143 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 144 * \param condition The condition.
taoxh 0:ee91220d7bea 145 *
taoxh 0:ee91220d7bea 146 * \hideinitializer
taoxh 0:ee91220d7bea 147 */
taoxh 0:ee91220d7bea 148 #define PT_WAIT_UNTIL(pt, condition) \
taoxh 0:ee91220d7bea 149 do { \
taoxh 0:ee91220d7bea 150 LC_SET((pt)->lc); \
taoxh 0:ee91220d7bea 151 if(!(condition)) { \
taoxh 0:ee91220d7bea 152 return PT_WAITING; \
taoxh 0:ee91220d7bea 153 } \
taoxh 0:ee91220d7bea 154 } while(0)
taoxh 0:ee91220d7bea 155
taoxh 0:ee91220d7bea 156 /**
taoxh 0:ee91220d7bea 157 * Block and wait while condition is true.
taoxh 0:ee91220d7bea 158 *
taoxh 0:ee91220d7bea 159 * This function blocks and waits while condition is true. See
taoxh 0:ee91220d7bea 160 * PT_WAIT_UNTIL().
taoxh 0:ee91220d7bea 161 *
taoxh 0:ee91220d7bea 162 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 163 * \param cond The condition.
taoxh 0:ee91220d7bea 164 *
taoxh 0:ee91220d7bea 165 * \hideinitializer
taoxh 0:ee91220d7bea 166 */
taoxh 0:ee91220d7bea 167 #define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
taoxh 0:ee91220d7bea 168
taoxh 0:ee91220d7bea 169 /** @} */
taoxh 0:ee91220d7bea 170
taoxh 0:ee91220d7bea 171 /**
taoxh 0:ee91220d7bea 172 * \name Hierarchical protothreads
taoxh 0:ee91220d7bea 173 * @{
taoxh 0:ee91220d7bea 174 */
taoxh 0:ee91220d7bea 175
taoxh 0:ee91220d7bea 176 /**
taoxh 0:ee91220d7bea 177 * Block and wait until a child protothread completes.
taoxh 0:ee91220d7bea 178 *
taoxh 0:ee91220d7bea 179 * This macro schedules a child protothread. The current protothread
taoxh 0:ee91220d7bea 180 * will block until the child protothread completes.
taoxh 0:ee91220d7bea 181 *
taoxh 0:ee91220d7bea 182 * \note The child protothread must be manually initialized with the
taoxh 0:ee91220d7bea 183 * PT_INIT() function before this function is used.
taoxh 0:ee91220d7bea 184 *
taoxh 0:ee91220d7bea 185 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 186 * \param thread The child protothread with arguments
taoxh 0:ee91220d7bea 187 *
taoxh 0:ee91220d7bea 188 * \sa PT_SPAWN()
taoxh 0:ee91220d7bea 189 *
taoxh 0:ee91220d7bea 190 * \hideinitializer
taoxh 0:ee91220d7bea 191 */
taoxh 0:ee91220d7bea 192 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
taoxh 0:ee91220d7bea 193
taoxh 0:ee91220d7bea 194 /**
taoxh 0:ee91220d7bea 195 * Spawn a child protothread and wait until it exits.
taoxh 0:ee91220d7bea 196 *
taoxh 0:ee91220d7bea 197 * This macro spawns a child protothread and waits until it exits. The
taoxh 0:ee91220d7bea 198 * macro can only be used within a protothread.
taoxh 0:ee91220d7bea 199 *
taoxh 0:ee91220d7bea 200 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 201 * \param child A pointer to the child protothread's control structure.
taoxh 0:ee91220d7bea 202 * \param thread The child protothread with arguments
taoxh 0:ee91220d7bea 203 *
taoxh 0:ee91220d7bea 204 * \hideinitializer
taoxh 0:ee91220d7bea 205 */
taoxh 0:ee91220d7bea 206 #define PT_SPAWN(pt, child, thread) \
taoxh 0:ee91220d7bea 207 do { \
taoxh 0:ee91220d7bea 208 PT_INIT((child)); \
taoxh 0:ee91220d7bea 209 PT_WAIT_THREAD((pt), (thread)); \
taoxh 0:ee91220d7bea 210 } while(0)
taoxh 0:ee91220d7bea 211
taoxh 0:ee91220d7bea 212 /** @} */
taoxh 0:ee91220d7bea 213
taoxh 0:ee91220d7bea 214 /**
taoxh 0:ee91220d7bea 215 * \name Exiting and restarting
taoxh 0:ee91220d7bea 216 * @{
taoxh 0:ee91220d7bea 217 */
taoxh 0:ee91220d7bea 218
taoxh 0:ee91220d7bea 219 /**
taoxh 0:ee91220d7bea 220 * Restart the protothread.
taoxh 0:ee91220d7bea 221 *
taoxh 0:ee91220d7bea 222 * This macro will block and cause the running protothread to restart
taoxh 0:ee91220d7bea 223 * its execution at the place of the PT_BEGIN() call.
taoxh 0:ee91220d7bea 224 *
taoxh 0:ee91220d7bea 225 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 226 *
taoxh 0:ee91220d7bea 227 * \hideinitializer
taoxh 0:ee91220d7bea 228 */
taoxh 0:ee91220d7bea 229 #define PT_RESTART(pt) \
taoxh 0:ee91220d7bea 230 do { \
taoxh 0:ee91220d7bea 231 PT_INIT(pt); \
taoxh 0:ee91220d7bea 232 return PT_WAITING; \
taoxh 0:ee91220d7bea 233 } while(0)
taoxh 0:ee91220d7bea 234
taoxh 0:ee91220d7bea 235 /**
taoxh 0:ee91220d7bea 236 * Exit the protothread.
taoxh 0:ee91220d7bea 237 *
taoxh 0:ee91220d7bea 238 * This macro causes the protothread to exit. If the protothread was
taoxh 0:ee91220d7bea 239 * spawned by another protothread, the parent protothread will become
taoxh 0:ee91220d7bea 240 * unblocked and can continue to run.
taoxh 0:ee91220d7bea 241 *
taoxh 0:ee91220d7bea 242 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 243 *
taoxh 0:ee91220d7bea 244 * \hideinitializer
taoxh 0:ee91220d7bea 245 */
taoxh 0:ee91220d7bea 246 #define PT_EXIT(pt) \
taoxh 0:ee91220d7bea 247 do { \
taoxh 0:ee91220d7bea 248 PT_INIT(pt); \
taoxh 0:ee91220d7bea 249 return PT_EXITED; \
taoxh 0:ee91220d7bea 250 } while(0)
taoxh 0:ee91220d7bea 251
taoxh 0:ee91220d7bea 252 /** @} */
taoxh 0:ee91220d7bea 253
taoxh 0:ee91220d7bea 254 /**
taoxh 0:ee91220d7bea 255 * \name Calling a protothread
taoxh 0:ee91220d7bea 256 * @{
taoxh 0:ee91220d7bea 257 */
taoxh 0:ee91220d7bea 258
taoxh 0:ee91220d7bea 259 /**
taoxh 0:ee91220d7bea 260 * Schedule a protothread.
taoxh 0:ee91220d7bea 261 *
taoxh 0:ee91220d7bea 262 * This function shedules a protothread. The return value of the
taoxh 0:ee91220d7bea 263 * function is non-zero if the protothread is running or zero if the
taoxh 0:ee91220d7bea 264 * protothread has exited.
taoxh 0:ee91220d7bea 265 *
taoxh 0:ee91220d7bea 266 * \param f The call to the C function implementing the protothread to
taoxh 0:ee91220d7bea 267 * be scheduled
taoxh 0:ee91220d7bea 268 *
taoxh 0:ee91220d7bea 269 * \hideinitializer
taoxh 0:ee91220d7bea 270 */
taoxh 0:ee91220d7bea 271 #define PT_SCHEDULE(f) ((f) < PT_EXITED)
taoxh 0:ee91220d7bea 272
taoxh 0:ee91220d7bea 273 /** @} */
taoxh 0:ee91220d7bea 274
taoxh 0:ee91220d7bea 275 /**
taoxh 0:ee91220d7bea 276 * \name Yielding from a protothread
taoxh 0:ee91220d7bea 277 * @{
taoxh 0:ee91220d7bea 278 */
taoxh 0:ee91220d7bea 279
taoxh 0:ee91220d7bea 280 /**
taoxh 0:ee91220d7bea 281 * Yield from the current protothread.
taoxh 0:ee91220d7bea 282 *
taoxh 0:ee91220d7bea 283 * This function will yield the protothread, thereby allowing other
taoxh 0:ee91220d7bea 284 * processing to take place in the system.
taoxh 0:ee91220d7bea 285 *
taoxh 0:ee91220d7bea 286 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 287 *
taoxh 0:ee91220d7bea 288 * \hideinitializer
taoxh 0:ee91220d7bea 289 */
taoxh 0:ee91220d7bea 290 #define PT_YIELD(pt) \
taoxh 0:ee91220d7bea 291 do { \
taoxh 0:ee91220d7bea 292 PT_YIELD_FLAG = 0; \
taoxh 0:ee91220d7bea 293 LC_SET((pt)->lc); \
taoxh 0:ee91220d7bea 294 if(PT_YIELD_FLAG == 0) { \
taoxh 0:ee91220d7bea 295 return PT_YIELDED; \
taoxh 0:ee91220d7bea 296 } \
taoxh 0:ee91220d7bea 297 } while(0)
taoxh 0:ee91220d7bea 298
taoxh 0:ee91220d7bea 299 /**
taoxh 0:ee91220d7bea 300 * \brief Yield from the protothread until a condition occurs.
taoxh 0:ee91220d7bea 301 * \param pt A pointer to the protothread control structure.
taoxh 0:ee91220d7bea 302 * \param cond The condition.
taoxh 0:ee91220d7bea 303 *
taoxh 0:ee91220d7bea 304 * This function will yield the protothread, until the
taoxh 0:ee91220d7bea 305 * specified condition evaluates to true.
taoxh 0:ee91220d7bea 306 *
taoxh 0:ee91220d7bea 307 *
taoxh 0:ee91220d7bea 308 * \hideinitializer
taoxh 0:ee91220d7bea 309 */
taoxh 0:ee91220d7bea 310 #define PT_YIELD_UNTIL(pt, cond) \
taoxh 0:ee91220d7bea 311 do { \
taoxh 0:ee91220d7bea 312 PT_YIELD_FLAG = 0; \
taoxh 0:ee91220d7bea 313 LC_SET((pt)->lc); \
taoxh 0:ee91220d7bea 314 if((PT_YIELD_FLAG == 0) || !(cond)) { \
taoxh 0:ee91220d7bea 315 return PT_YIELDED; \
taoxh 0:ee91220d7bea 316 } \
taoxh 0:ee91220d7bea 317 } while(0)
taoxh 0:ee91220d7bea 318
taoxh 0:ee91220d7bea 319 /** @} */
taoxh 0:ee91220d7bea 320
taoxh 0:ee91220d7bea 321 #endif /* __PT_H__ */
taoxh 0:ee91220d7bea 322
taoxh 0:ee91220d7bea 323 /** @} */