Steven He / Mbed 2 deprecated StringMatchingProtothread

Dependencies:   mbed

Committer:
StevenHe
Date:
Wed Dec 01 04:39:00 2010 +0000
Revision:
0:544b5f6ad832

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
StevenHe 0:544b5f6ad832 1 /*
StevenHe 0:544b5f6ad832 2 * Copyright (c) 2004, Swedish Institute of Computer Science.
StevenHe 0:544b5f6ad832 3 * All rights reserved.
StevenHe 0:544b5f6ad832 4 *
StevenHe 0:544b5f6ad832 5 * Redistribution and use in source and binary forms, with or without
StevenHe 0:544b5f6ad832 6 * modification, are permitted provided that the following conditions
StevenHe 0:544b5f6ad832 7 * are met:
StevenHe 0:544b5f6ad832 8 * 1. Redistributions of source code must retain the above copyright
StevenHe 0:544b5f6ad832 9 * notice, this list of conditions and the following disclaimer.
StevenHe 0:544b5f6ad832 10 * 2. Redistributions in binary form must reproduce the above copyright
StevenHe 0:544b5f6ad832 11 * notice, this list of conditions and the following disclaimer in the
StevenHe 0:544b5f6ad832 12 * documentation and/or other materials provided with the distribution.
StevenHe 0:544b5f6ad832 13 * 3. Neither the name of the Institute nor the names of its contributors
StevenHe 0:544b5f6ad832 14 * may be used to endorse or promote products derived from this software
StevenHe 0:544b5f6ad832 15 * without specific prior written permission.
StevenHe 0:544b5f6ad832 16 *
StevenHe 0:544b5f6ad832 17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
StevenHe 0:544b5f6ad832 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
StevenHe 0:544b5f6ad832 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
StevenHe 0:544b5f6ad832 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
StevenHe 0:544b5f6ad832 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
StevenHe 0:544b5f6ad832 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
StevenHe 0:544b5f6ad832 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
StevenHe 0:544b5f6ad832 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
StevenHe 0:544b5f6ad832 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
StevenHe 0:544b5f6ad832 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
StevenHe 0:544b5f6ad832 27 * SUCH DAMAGE.
StevenHe 0:544b5f6ad832 28 *
StevenHe 0:544b5f6ad832 29 * This file is part of the protothreads library.
StevenHe 0:544b5f6ad832 30 *
StevenHe 0:544b5f6ad832 31 * Author: Adam Dunkels <adam@sics.se>
StevenHe 0:544b5f6ad832 32 *
StevenHe 0:544b5f6ad832 33 * $Id: pt-sem.h,v 1.2 2005/02/24 10:36:59 adam Exp $
StevenHe 0:544b5f6ad832 34 */
StevenHe 0:544b5f6ad832 35
StevenHe 0:544b5f6ad832 36 /**
StevenHe 0:544b5f6ad832 37 * \addtogroup pt
StevenHe 0:544b5f6ad832 38 * @{
StevenHe 0:544b5f6ad832 39 */
StevenHe 0:544b5f6ad832 40
StevenHe 0:544b5f6ad832 41 /**
StevenHe 0:544b5f6ad832 42 * \defgroup ptsem Protothread semaphores
StevenHe 0:544b5f6ad832 43 * @{
StevenHe 0:544b5f6ad832 44 *
StevenHe 0:544b5f6ad832 45 * This module implements counting semaphores on top of
StevenHe 0:544b5f6ad832 46 * protothreads. Semaphores are a synchronization primitive that
StevenHe 0:544b5f6ad832 47 * provide two operations: "wait" and "signal". The "wait" operation
StevenHe 0:544b5f6ad832 48 * checks the semaphore counter and blocks the thread if the counter
StevenHe 0:544b5f6ad832 49 * is zero. The "signal" operation increases the semaphore counter but
StevenHe 0:544b5f6ad832 50 * does not block. If another thread has blocked waiting for the
StevenHe 0:544b5f6ad832 51 * semaphore that is signalled, the blocked thread will become
StevenHe 0:544b5f6ad832 52 * runnable again.
StevenHe 0:544b5f6ad832 53 *
StevenHe 0:544b5f6ad832 54 * Semaphores can be used to implement other, more structured,
StevenHe 0:544b5f6ad832 55 * synchronization primitives such as monitors and message
StevenHe 0:544b5f6ad832 56 * queues/bounded buffers (see below).
StevenHe 0:544b5f6ad832 57 *
StevenHe 0:544b5f6ad832 58 * The following example shows how the producer-consumer problem, also
StevenHe 0:544b5f6ad832 59 * known as the bounded buffer problem, can be solved using
StevenHe 0:544b5f6ad832 60 * protothreads and semaphores. Notes on the program follow after the
StevenHe 0:544b5f6ad832 61 * example.
StevenHe 0:544b5f6ad832 62 *
StevenHe 0:544b5f6ad832 63 \code
StevenHe 0:544b5f6ad832 64 #include "pt-sem.h"
StevenHe 0:544b5f6ad832 65
StevenHe 0:544b5f6ad832 66 #define NUM_ITEMS 32
StevenHe 0:544b5f6ad832 67 #define BUFSIZE 8
StevenHe 0:544b5f6ad832 68
StevenHe 0:544b5f6ad832 69 static struct pt_sem mutex, full, empty;
StevenHe 0:544b5f6ad832 70
StevenHe 0:544b5f6ad832 71 PT_THREAD(producer(struct pt *pt))
StevenHe 0:544b5f6ad832 72 {
StevenHe 0:544b5f6ad832 73 static int produced;
StevenHe 0:544b5f6ad832 74
StevenHe 0:544b5f6ad832 75 PT_BEGIN(pt);
StevenHe 0:544b5f6ad832 76
StevenHe 0:544b5f6ad832 77 for(produced = 0; produced < NUM_ITEMS; ++produced) {
StevenHe 0:544b5f6ad832 78
StevenHe 0:544b5f6ad832 79 PT_SEM_WAIT(pt, &full);
StevenHe 0:544b5f6ad832 80
StevenHe 0:544b5f6ad832 81 PT_SEM_WAIT(pt, &mutex);
StevenHe 0:544b5f6ad832 82 add_to_buffer(produce_item());
StevenHe 0:544b5f6ad832 83 PT_SEM_SIGNAL(pt, &mutex);
StevenHe 0:544b5f6ad832 84
StevenHe 0:544b5f6ad832 85 PT_SEM_SIGNAL(pt, &empty);
StevenHe 0:544b5f6ad832 86 }
StevenHe 0:544b5f6ad832 87
StevenHe 0:544b5f6ad832 88 PT_END(pt);
StevenHe 0:544b5f6ad832 89 }
StevenHe 0:544b5f6ad832 90
StevenHe 0:544b5f6ad832 91 PT_THREAD(consumer(struct pt *pt))
StevenHe 0:544b5f6ad832 92 {
StevenHe 0:544b5f6ad832 93 static int consumed;
StevenHe 0:544b5f6ad832 94
StevenHe 0:544b5f6ad832 95 PT_BEGIN(pt);
StevenHe 0:544b5f6ad832 96
StevenHe 0:544b5f6ad832 97 for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
StevenHe 0:544b5f6ad832 98
StevenHe 0:544b5f6ad832 99 PT_SEM_WAIT(pt, &empty);
StevenHe 0:544b5f6ad832 100
StevenHe 0:544b5f6ad832 101 PT_SEM_WAIT(pt, &mutex);
StevenHe 0:544b5f6ad832 102 consume_item(get_from_buffer());
StevenHe 0:544b5f6ad832 103 PT_SEM_SIGNAL(pt, &mutex);
StevenHe 0:544b5f6ad832 104
StevenHe 0:544b5f6ad832 105 PT_SEM_SIGNAL(pt, &full);
StevenHe 0:544b5f6ad832 106 }
StevenHe 0:544b5f6ad832 107
StevenHe 0:544b5f6ad832 108 PT_END(pt);
StevenHe 0:544b5f6ad832 109 }
StevenHe 0:544b5f6ad832 110
StevenHe 0:544b5f6ad832 111 PT_THREAD(driver_thread(struct pt *pt))
StevenHe 0:544b5f6ad832 112 {
StevenHe 0:544b5f6ad832 113 static struct pt pt_producer, pt_consumer;
StevenHe 0:544b5f6ad832 114
StevenHe 0:544b5f6ad832 115 PT_BEGIN(pt);
StevenHe 0:544b5f6ad832 116
StevenHe 0:544b5f6ad832 117 PT_SEM_INIT(&empty, 0);
StevenHe 0:544b5f6ad832 118 PT_SEM_INIT(&full, BUFSIZE);
StevenHe 0:544b5f6ad832 119 PT_SEM_INIT(&mutex, 1);
StevenHe 0:544b5f6ad832 120
StevenHe 0:544b5f6ad832 121 PT_INIT(&pt_producer);
StevenHe 0:544b5f6ad832 122 PT_INIT(&pt_consumer);
StevenHe 0:544b5f6ad832 123
StevenHe 0:544b5f6ad832 124 PT_WAIT_THREAD(pt, producer(&pt_producer) &
StevenHe 0:544b5f6ad832 125 consumer(&pt_consumer));
StevenHe 0:544b5f6ad832 126
StevenHe 0:544b5f6ad832 127 PT_END(pt);
StevenHe 0:544b5f6ad832 128 }
StevenHe 0:544b5f6ad832 129 \endcode
StevenHe 0:544b5f6ad832 130 *
StevenHe 0:544b5f6ad832 131 * The program uses three protothreads: one protothread that
StevenHe 0:544b5f6ad832 132 * implements the consumer, one thread that implements the producer,
StevenHe 0:544b5f6ad832 133 * and one protothread that drives the two other protothreads. The
StevenHe 0:544b5f6ad832 134 * program uses three semaphores: "full", "empty" and "mutex". The
StevenHe 0:544b5f6ad832 135 * "mutex" semaphore is used to provide mutual exclusion for the
StevenHe 0:544b5f6ad832 136 * buffer, the "empty" semaphore is used to block the consumer is the
StevenHe 0:544b5f6ad832 137 * buffer is empty, and the "full" semaphore is used to block the
StevenHe 0:544b5f6ad832 138 * producer is the buffer is full.
StevenHe 0:544b5f6ad832 139 *
StevenHe 0:544b5f6ad832 140 * The "driver_thread" holds two protothread state variables,
StevenHe 0:544b5f6ad832 141 * "pt_producer" and "pt_consumer". It is important to note that both
StevenHe 0:544b5f6ad832 142 * these variables are declared as <i>static</i>. If the static
StevenHe 0:544b5f6ad832 143 * keyword is not used, both variables are stored on the stack. Since
StevenHe 0:544b5f6ad832 144 * protothreads do not store the stack, these variables may be
StevenHe 0:544b5f6ad832 145 * overwritten during a protothread wait operation. Similarly, both
StevenHe 0:544b5f6ad832 146 * the "consumer" and "producer" protothreads declare their local
StevenHe 0:544b5f6ad832 147 * variables as static, to avoid them being stored on the stack.
StevenHe 0:544b5f6ad832 148 *
StevenHe 0:544b5f6ad832 149 *
StevenHe 0:544b5f6ad832 150 */
StevenHe 0:544b5f6ad832 151
StevenHe 0:544b5f6ad832 152 /**
StevenHe 0:544b5f6ad832 153 * \file
StevenHe 0:544b5f6ad832 154 * Couting semaphores implemented on protothreads
StevenHe 0:544b5f6ad832 155 * \author
StevenHe 0:544b5f6ad832 156 * Adam Dunkels <adam@sics.se>
StevenHe 0:544b5f6ad832 157 *
StevenHe 0:544b5f6ad832 158 */
StevenHe 0:544b5f6ad832 159
StevenHe 0:544b5f6ad832 160 #ifndef __PT_SEM_H__
StevenHe 0:544b5f6ad832 161 #define __PT_SEM_H__
StevenHe 0:544b5f6ad832 162
StevenHe 0:544b5f6ad832 163 #include "pt.h"
StevenHe 0:544b5f6ad832 164
StevenHe 0:544b5f6ad832 165 struct pt_sem {
StevenHe 0:544b5f6ad832 166 unsigned int count;
StevenHe 0:544b5f6ad832 167 };
StevenHe 0:544b5f6ad832 168
StevenHe 0:544b5f6ad832 169 /**
StevenHe 0:544b5f6ad832 170 * Initialize a semaphore
StevenHe 0:544b5f6ad832 171 *
StevenHe 0:544b5f6ad832 172 * This macro initializes a semaphore with a value for the
StevenHe 0:544b5f6ad832 173 * counter. Internally, the semaphores use an "unsigned int" to
StevenHe 0:544b5f6ad832 174 * represent the counter, and therefore the "count" argument should be
StevenHe 0:544b5f6ad832 175 * within range of an unsigned int.
StevenHe 0:544b5f6ad832 176 *
StevenHe 0:544b5f6ad832 177 * \param s (struct pt_sem *) A pointer to the pt_sem struct
StevenHe 0:544b5f6ad832 178 * representing the semaphore
StevenHe 0:544b5f6ad832 179 *
StevenHe 0:544b5f6ad832 180 * \param c (unsigned int) The initial count of the semaphore.
StevenHe 0:544b5f6ad832 181 * \hideinitializer
StevenHe 0:544b5f6ad832 182 */
StevenHe 0:544b5f6ad832 183 #define PT_SEM_INIT(s, c) (s)->count = c
StevenHe 0:544b5f6ad832 184
StevenHe 0:544b5f6ad832 185 /**
StevenHe 0:544b5f6ad832 186 * Wait for a semaphore
StevenHe 0:544b5f6ad832 187 *
StevenHe 0:544b5f6ad832 188 * This macro carries out the "wait" operation on the semaphore. The
StevenHe 0:544b5f6ad832 189 * wait operation causes the protothread to block while the counter is
StevenHe 0:544b5f6ad832 190 * zero. When the counter reaches a value larger than zero, the
StevenHe 0:544b5f6ad832 191 * protothread will continue.
StevenHe 0:544b5f6ad832 192 *
StevenHe 0:544b5f6ad832 193 * \param pt (struct pt *) A pointer to the protothread (struct pt) in
StevenHe 0:544b5f6ad832 194 * which the operation is executed.
StevenHe 0:544b5f6ad832 195 *
StevenHe 0:544b5f6ad832 196 * \param s (struct pt_sem *) A pointer to the pt_sem struct
StevenHe 0:544b5f6ad832 197 * representing the semaphore
StevenHe 0:544b5f6ad832 198 *
StevenHe 0:544b5f6ad832 199 * \hideinitializer
StevenHe 0:544b5f6ad832 200 */
StevenHe 0:544b5f6ad832 201 #define PT_SEM_WAIT(pt, s) \
StevenHe 0:544b5f6ad832 202 do { \
StevenHe 0:544b5f6ad832 203 PT_WAIT_UNTIL(pt, (s)->count > 0); \
StevenHe 0:544b5f6ad832 204 --(s)->count; \
StevenHe 0:544b5f6ad832 205 } while(0)
StevenHe 0:544b5f6ad832 206
StevenHe 0:544b5f6ad832 207 /**
StevenHe 0:544b5f6ad832 208 * Signal a semaphore
StevenHe 0:544b5f6ad832 209 *
StevenHe 0:544b5f6ad832 210 * This macro carries out the "signal" operation on the semaphore. The
StevenHe 0:544b5f6ad832 211 * signal operation increments the counter inside the semaphore, which
StevenHe 0:544b5f6ad832 212 * eventually will cause waiting protothreads to continue executing.
StevenHe 0:544b5f6ad832 213 *
StevenHe 0:544b5f6ad832 214 * \param pt (struct pt *) A pointer to the protothread (struct pt) in
StevenHe 0:544b5f6ad832 215 * which the operation is executed.
StevenHe 0:544b5f6ad832 216 *
StevenHe 0:544b5f6ad832 217 * \param s (struct pt_sem *) A pointer to the pt_sem struct
StevenHe 0:544b5f6ad832 218 * representing the semaphore
StevenHe 0:544b5f6ad832 219 *
StevenHe 0:544b5f6ad832 220 * \hideinitializer
StevenHe 0:544b5f6ad832 221 */
StevenHe 0:544b5f6ad832 222 #define PT_SEM_SIGNAL(pt, s) ++(s)->count
StevenHe 0:544b5f6ad832 223
StevenHe 0:544b5f6ad832 224 #endif /* __PT_SEM_H__ */
StevenHe 0:544b5f6ad832 225
StevenHe 0:544b5f6ad832 226 /** @} */
StevenHe 0:544b5f6ad832 227 /** @} */
StevenHe 0:544b5f6ad832 228