mbed-os

Fork of mbed-os by erkin yucel

Committer:
xuaner
Date:
Thu Jul 20 14:26:57 2017 +0000
Revision:
1:3deb71413561
Parent:
0:f269e3021894
mbed_os

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1 /* mbed Microcontroller Library
elessair 0:f269e3021894 2 * Copyright (c) 2006-2012 ARM Limited
elessair 0:f269e3021894 3 *
elessair 0:f269e3021894 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
elessair 0:f269e3021894 5 * of this software and associated documentation files (the "Software"), to deal
elessair 0:f269e3021894 6 * in the Software without restriction, including without limitation the rights
elessair 0:f269e3021894 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
elessair 0:f269e3021894 8 * copies of the Software, and to permit persons to whom the Software is
elessair 0:f269e3021894 9 * furnished to do so, subject to the following conditions:
elessair 0:f269e3021894 10 *
elessair 0:f269e3021894 11 * The above copyright notice and this permission notice shall be included in
elessair 0:f269e3021894 12 * all copies or substantial portions of the Software.
elessair 0:f269e3021894 13 *
elessair 0:f269e3021894 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
elessair 0:f269e3021894 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
elessair 0:f269e3021894 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
elessair 0:f269e3021894 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
elessair 0:f269e3021894 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
elessair 0:f269e3021894 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
elessair 0:f269e3021894 20 * SOFTWARE.
elessair 0:f269e3021894 21 */
elessair 0:f269e3021894 22 #ifndef THREAD_H
elessair 0:f269e3021894 23 #define THREAD_H
elessair 0:f269e3021894 24
elessair 0:f269e3021894 25 #include <stdint.h>
elessair 0:f269e3021894 26 #include "cmsis_os.h"
elessair 0:f269e3021894 27 #include "platform/Callback.h"
elessair 0:f269e3021894 28 #include "platform/toolchain.h"
elessair 0:f269e3021894 29 #include "rtos/Semaphore.h"
elessair 0:f269e3021894 30 #include "rtos/Mutex.h"
elessair 0:f269e3021894 31
elessair 0:f269e3021894 32 namespace rtos {
elessair 0:f269e3021894 33 /** \addtogroup rtos */
elessair 0:f269e3021894 34 /** @{*/
elessair 0:f269e3021894 35
elessair 0:f269e3021894 36 /** The Thread class allow defining, creating, and controlling thread functions in the system.
elessair 0:f269e3021894 37 *
elessair 0:f269e3021894 38 * Example:
elessair 0:f269e3021894 39 * @code
elessair 0:f269e3021894 40 * #include "mbed.h"
elessair 0:f269e3021894 41 * #include "rtos.h"
elessair 0:f269e3021894 42 *
elessair 0:f269e3021894 43 * Thread thread;
elessair 0:f269e3021894 44 * DigitalOut led1(LED1);
elessair 0:f269e3021894 45 * volatile bool running = true;
elessair 0:f269e3021894 46 *
elessair 0:f269e3021894 47 * // Blink function toggles the led in a long running loop
elessair 0:f269e3021894 48 * void blink(DigitalOut *led) {
elessair 0:f269e3021894 49 * while (running) {
elessair 0:f269e3021894 50 * *led = !*led;
elessair 0:f269e3021894 51 * Thread::wait(1000);
elessair 0:f269e3021894 52 * }
elessair 0:f269e3021894 53 * }
elessair 0:f269e3021894 54 *
elessair 0:f269e3021894 55 * // Spawns a thread to run blink for 5 seconds
elessair 0:f269e3021894 56 * int main() {
elessair 0:f269e3021894 57 * thread.start(led1, blink);
elessair 0:f269e3021894 58 * Thread::wait(5000);
elessair 0:f269e3021894 59 * running = false;
elessair 0:f269e3021894 60 * thread.join();
elessair 0:f269e3021894 61 * }
elessair 0:f269e3021894 62 * @endcode
elessair 0:f269e3021894 63 */
elessair 0:f269e3021894 64 class Thread {
elessair 0:f269e3021894 65 public:
elessair 0:f269e3021894 66 /** Allocate a new thread without starting execution
elessair 0:f269e3021894 67 @param priority initial priority of the thread function. (default: osPriorityNormal).
elessair 0:f269e3021894 68 @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
elessair 0:f269e3021894 69 @param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
elessair 0:f269e3021894 70 */
elessair 0:f269e3021894 71 Thread(osPriority priority=osPriorityNormal,
elessair 0:f269e3021894 72 uint32_t stack_size=DEFAULT_STACK_SIZE,
elessair 0:f269e3021894 73 unsigned char *stack_pointer=NULL) {
elessair 0:f269e3021894 74 constructor(priority, stack_size, stack_pointer);
elessair 0:f269e3021894 75 }
elessair 0:f269e3021894 76
elessair 0:f269e3021894 77 /** Create a new thread, and start it executing the specified function.
elessair 0:f269e3021894 78 @param task function to be executed by this thread.
elessair 0:f269e3021894 79 @param argument pointer that is passed to the thread function as start argument. (default: NULL).
elessair 0:f269e3021894 80 @param priority initial priority of the thread function. (default: osPriorityNormal).
elessair 0:f269e3021894 81 @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
elessair 0:f269e3021894 82 @param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
elessair 0:f269e3021894 83 @deprecated
elessair 0:f269e3021894 84 Thread-spawning constructors hide errors. Replaced by thread.start(task).
elessair 0:f269e3021894 85
elessair 0:f269e3021894 86 @code
elessair 0:f269e3021894 87 Thread thread(priority, stack_size, stack_pointer);
elessair 0:f269e3021894 88
elessair 0:f269e3021894 89 osStatus status = thread.start(task);
elessair 0:f269e3021894 90 if (status != osOK) {
elessair 0:f269e3021894 91 error("oh no!");
elessair 0:f269e3021894 92 }
elessair 0:f269e3021894 93 @endcode
elessair 0:f269e3021894 94 */
elessair 0:f269e3021894 95 MBED_DEPRECATED_SINCE("mbed-os-5.1",
elessair 0:f269e3021894 96 "Thread-spawning constructors hide errors. "
elessair 0:f269e3021894 97 "Replaced by thread.start(task).")
elessair 0:f269e3021894 98 Thread(mbed::Callback<void()> task,
elessair 0:f269e3021894 99 osPriority priority=osPriorityNormal,
elessair 0:f269e3021894 100 uint32_t stack_size=DEFAULT_STACK_SIZE,
elessair 0:f269e3021894 101 unsigned char *stack_pointer=NULL) {
elessair 0:f269e3021894 102 constructor(task, priority, stack_size, stack_pointer);
elessair 0:f269e3021894 103 }
elessair 0:f269e3021894 104
elessair 0:f269e3021894 105 /** Create a new thread, and start it executing the specified function.
elessair 0:f269e3021894 106 @param obj argument to task.
elessair 0:f269e3021894 107 @param method function to be executed by this thread.
elessair 0:f269e3021894 108 @param argument pointer that is passed to the thread function as start argument. (default: NULL).
elessair 0:f269e3021894 109 @param priority initial priority of the thread function. (default: osPriorityNormal).
elessair 0:f269e3021894 110 @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
elessair 0:f269e3021894 111 @param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
elessair 0:f269e3021894 112 @deprecated
elessair 0:f269e3021894 113 Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
elessair 0:f269e3021894 114
elessair 0:f269e3021894 115 @code
elessair 0:f269e3021894 116 Thread thread(priority, stack_size, stack_pointer);
elessair 0:f269e3021894 117
elessair 0:f269e3021894 118 osStatus status = thread.start(callback(task, argument));
elessair 0:f269e3021894 119 if (status != osOK) {
elessair 0:f269e3021894 120 error("oh no!");
elessair 0:f269e3021894 121 }
elessair 0:f269e3021894 122 @endcode
elessair 0:f269e3021894 123 */
elessair 0:f269e3021894 124 template <typename T>
elessair 0:f269e3021894 125 MBED_DEPRECATED_SINCE("mbed-os-5.1",
elessair 0:f269e3021894 126 "Thread-spawning constructors hide errors. "
elessair 0:f269e3021894 127 "Replaced by thread.start(callback(task, argument)).")
elessair 0:f269e3021894 128 Thread(T *argument, void (T::*task)(),
elessair 0:f269e3021894 129 osPriority priority=osPriorityNormal,
elessair 0:f269e3021894 130 uint32_t stack_size=DEFAULT_STACK_SIZE,
elessair 0:f269e3021894 131 unsigned char *stack_pointer=NULL) {
elessair 0:f269e3021894 132 constructor(mbed::callback(task, argument),
elessair 0:f269e3021894 133 priority, stack_size, stack_pointer);
elessair 0:f269e3021894 134 }
elessair 0:f269e3021894 135
elessair 0:f269e3021894 136 /** Create a new thread, and start it executing the specified function.
elessair 0:f269e3021894 137 @param obj argument to task.
elessair 0:f269e3021894 138 @param method function to be executed by this thread.
elessair 0:f269e3021894 139 @param argument pointer that is passed to the thread function as start argument. (default: NULL).
elessair 0:f269e3021894 140 @param priority initial priority of the thread function. (default: osPriorityNormal).
elessair 0:f269e3021894 141 @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
elessair 0:f269e3021894 142 @param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
elessair 0:f269e3021894 143 @deprecated
elessair 0:f269e3021894 144 Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
elessair 0:f269e3021894 145
elessair 0:f269e3021894 146 @code
elessair 0:f269e3021894 147 Thread thread(priority, stack_size, stack_pointer);
elessair 0:f269e3021894 148
elessair 0:f269e3021894 149 osStatus status = thread.start(callback(task, argument));
elessair 0:f269e3021894 150 if (status != osOK) {
elessair 0:f269e3021894 151 error("oh no!");
elessair 0:f269e3021894 152 }
elessair 0:f269e3021894 153 @endcode
elessair 0:f269e3021894 154 */
elessair 0:f269e3021894 155 template <typename T>
elessair 0:f269e3021894 156 MBED_DEPRECATED_SINCE("mbed-os-5.1",
elessair 0:f269e3021894 157 "Thread-spawning constructors hide errors. "
elessair 0:f269e3021894 158 "Replaced by thread.start(callback(task, argument)).")
elessair 0:f269e3021894 159 Thread(T *argument, void (*task)(T *),
elessair 0:f269e3021894 160 osPriority priority=osPriorityNormal,
elessair 0:f269e3021894 161 uint32_t stack_size=DEFAULT_STACK_SIZE,
elessair 0:f269e3021894 162 unsigned char *stack_pointer=NULL) {
elessair 0:f269e3021894 163 constructor(mbed::callback(task, argument),
elessair 0:f269e3021894 164 priority, stack_size, stack_pointer);
elessair 0:f269e3021894 165 }
elessair 0:f269e3021894 166
elessair 0:f269e3021894 167 /** Create a new thread, and start it executing the specified function.
elessair 0:f269e3021894 168 Provided for backwards compatibility
elessair 0:f269e3021894 169 @param task function to be executed by this thread.
elessair 0:f269e3021894 170 @param argument pointer that is passed to the thread function as start argument. (default: NULL).
elessair 0:f269e3021894 171 @param priority initial priority of the thread function. (default: osPriorityNormal).
elessair 0:f269e3021894 172 @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
elessair 0:f269e3021894 173 @param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
elessair 0:f269e3021894 174 @deprecated
elessair 0:f269e3021894 175 Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
elessair 0:f269e3021894 176
elessair 0:f269e3021894 177 @code
elessair 0:f269e3021894 178 Thread thread(priority, stack_size, stack_pointer);
elessair 0:f269e3021894 179
elessair 0:f269e3021894 180 osStatus status = thread.start(callback(task, argument));
elessair 0:f269e3021894 181 if (status != osOK) {
elessair 0:f269e3021894 182 error("oh no!");
elessair 0:f269e3021894 183 }
elessair 0:f269e3021894 184 @endcode
elessair 0:f269e3021894 185 */
elessair 0:f269e3021894 186 MBED_DEPRECATED_SINCE("mbed-os-5.1",
elessair 0:f269e3021894 187 "Thread-spawning constructors hide errors. "
elessair 0:f269e3021894 188 "Replaced by thread.start(callback(task, argument)).")
elessair 0:f269e3021894 189 Thread(void (*task)(void const *argument), void *argument=NULL,
elessair 0:f269e3021894 190 osPriority priority=osPriorityNormal,
elessair 0:f269e3021894 191 uint32_t stack_size=DEFAULT_STACK_SIZE,
elessair 0:f269e3021894 192 unsigned char *stack_pointer=NULL) {
elessair 0:f269e3021894 193 constructor(mbed::callback((void (*)(void *))task, argument),
elessair 0:f269e3021894 194 priority, stack_size, stack_pointer);
elessair 0:f269e3021894 195 }
elessair 0:f269e3021894 196
elessair 0:f269e3021894 197 /** Starts a thread executing the specified function.
elessair 0:f269e3021894 198 @param task function to be executed by this thread.
elessair 0:f269e3021894 199 @return status code that indicates the execution status of the function.
elessair 0:f269e3021894 200 */
elessair 0:f269e3021894 201 osStatus start(mbed::Callback<void()> task);
elessair 0:f269e3021894 202
elessair 0:f269e3021894 203 /** Starts a thread executing the specified function.
elessair 0:f269e3021894 204 @param obj argument to task
elessair 0:f269e3021894 205 @param method function to be executed by this thread.
elessair 0:f269e3021894 206 @return status code that indicates the execution status of the function.
elessair 0:f269e3021894 207 @deprecated
elessair 0:f269e3021894 208 The start function does not support cv-qualifiers. Replaced by start(callback(obj, method)).
elessair 0:f269e3021894 209 */
elessair 0:f269e3021894 210 template <typename T, typename M>
elessair 0:f269e3021894 211 MBED_DEPRECATED_SINCE("mbed-os-5.1",
elessair 0:f269e3021894 212 "The start function does not support cv-qualifiers. "
elessair 0:f269e3021894 213 "Replaced by thread.start(callback(obj, method)).")
elessair 0:f269e3021894 214 osStatus start(T *obj, M method) {
elessair 0:f269e3021894 215 return start(mbed::callback(obj, method));
elessair 0:f269e3021894 216 }
elessair 0:f269e3021894 217
elessair 0:f269e3021894 218 /** Wait for thread to terminate
elessair 0:f269e3021894 219 @return status code that indicates the execution status of the function.
elessair 0:f269e3021894 220 @note not callable from interrupt
elessair 0:f269e3021894 221 */
elessair 0:f269e3021894 222 osStatus join();
elessair 0:f269e3021894 223
elessair 0:f269e3021894 224 /** Terminate execution of a thread and remove it from Active Threads
elessair 0:f269e3021894 225 @return status code that indicates the execution status of the function.
elessair 0:f269e3021894 226 */
elessair 0:f269e3021894 227 osStatus terminate();
elessair 0:f269e3021894 228
elessair 0:f269e3021894 229 /** Set priority of an active thread
elessair 0:f269e3021894 230 @param priority new priority value for the thread function.
elessair 0:f269e3021894 231 @return status code that indicates the execution status of the function.
elessair 0:f269e3021894 232 */
elessair 0:f269e3021894 233 osStatus set_priority(osPriority priority);
elessair 0:f269e3021894 234
elessair 0:f269e3021894 235 /** Get priority of an active thread
elessair 0:f269e3021894 236 @return current priority value of the thread function.
elessair 0:f269e3021894 237 */
elessair 0:f269e3021894 238 osPriority get_priority();
elessair 0:f269e3021894 239
elessair 0:f269e3021894 240 /** Set the specified Signal Flags of an active thread.
elessair 0:f269e3021894 241 @param signals specifies the signal flags of the thread that should be set.
elessair 0:f269e3021894 242 @return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
elessair 0:f269e3021894 243 */
elessair 0:f269e3021894 244 int32_t signal_set(int32_t signals);
elessair 0:f269e3021894 245
elessair 0:f269e3021894 246 /** Clears the specified Signal Flags of an active thread.
elessair 0:f269e3021894 247 @param signals specifies the signal flags of the thread that should be cleared.
elessair 0:f269e3021894 248 @return resultant signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
elessair 0:f269e3021894 249 */
elessair 0:f269e3021894 250 int32_t signal_clr(int32_t signals);
elessair 0:f269e3021894 251
elessair 0:f269e3021894 252 /** State of the Thread */
elessair 0:f269e3021894 253 enum State {
elessair 0:f269e3021894 254 Inactive, /**< Not created or terminated */
elessair 0:f269e3021894 255 Ready, /**< Ready to run */
elessair 0:f269e3021894 256 Running, /**< Running */
elessair 0:f269e3021894 257 WaitingDelay, /**< Waiting for a delay to occur */
elessair 0:f269e3021894 258 WaitingInterval, /**< Waiting for an interval to occur */
elessair 0:f269e3021894 259 WaitingOr, /**< Waiting for one event in a set to occur */
elessair 0:f269e3021894 260 WaitingAnd, /**< Waiting for multiple events in a set to occur */
elessair 0:f269e3021894 261 WaitingSemaphore, /**< Waiting for a semaphore event to occur */
elessair 0:f269e3021894 262 WaitingMailbox, /**< Waiting for a mailbox event to occur */
elessair 0:f269e3021894 263 WaitingMutex, /**< Waiting for a mutex event to occur */
elessair 0:f269e3021894 264
elessair 0:f269e3021894 265 /* Not in sync with RTX below here */
elessair 0:f269e3021894 266 Deleted, /**< The task has been deleted */
elessair 0:f269e3021894 267 };
elessair 0:f269e3021894 268
elessair 0:f269e3021894 269 /** State of this Thread
elessair 0:f269e3021894 270 @return the State of this Thread
elessair 0:f269e3021894 271 */
elessair 0:f269e3021894 272 State get_state();
elessair 0:f269e3021894 273
elessair 0:f269e3021894 274 /** Get the total stack memory size for this Thread
elessair 0:f269e3021894 275 @return the total stack memory size in bytes
elessair 0:f269e3021894 276 */
elessair 0:f269e3021894 277 uint32_t stack_size();
elessair 0:f269e3021894 278
elessair 0:f269e3021894 279 /** Get the currently unused stack memory for this Thread
elessair 0:f269e3021894 280 @return the currently unused stack memory in bytes
elessair 0:f269e3021894 281 */
elessair 0:f269e3021894 282 uint32_t free_stack();
elessair 0:f269e3021894 283
elessair 0:f269e3021894 284 /** Get the currently used stack memory for this Thread
elessair 0:f269e3021894 285 @return the currently used stack memory in bytes
elessair 0:f269e3021894 286 */
elessair 0:f269e3021894 287 uint32_t used_stack();
elessair 0:f269e3021894 288
elessair 0:f269e3021894 289 /** Get the maximum stack memory usage to date for this Thread
elessair 0:f269e3021894 290 @return the maximum stack memory usage to date in bytes
elessair 0:f269e3021894 291 */
elessair 0:f269e3021894 292 uint32_t max_stack();
elessair 0:f269e3021894 293
elessair 0:f269e3021894 294 /** Wait for one or more Signal Flags to become signaled for the current RUNNING thread.
elessair 0:f269e3021894 295 @param signals wait until all specified signal flags set or 0 for any single signal flag.
elessair 0:f269e3021894 296 @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
elessair 0:f269e3021894 297 @return event flag information or error code.
elessair 0:f269e3021894 298 @note not callable from interrupt
elessair 0:f269e3021894 299 */
elessair 0:f269e3021894 300 static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
elessair 0:f269e3021894 301
elessair 0:f269e3021894 302 /** Wait for a specified time period in millisec:
elessair 0:f269e3021894 303 @param millisec time delay value
elessair 0:f269e3021894 304 @return status code that indicates the execution status of the function.
elessair 0:f269e3021894 305 @note not callable from interrupt
elessair 0:f269e3021894 306 */
elessair 0:f269e3021894 307 static osStatus wait(uint32_t millisec);
elessair 0:f269e3021894 308
elessair 0:f269e3021894 309 /** Pass control to next thread that is in state READY.
elessair 0:f269e3021894 310 @return status code that indicates the execution status of the function.
elessair 0:f269e3021894 311 @note not callable from interrupt
elessair 0:f269e3021894 312 */
elessair 0:f269e3021894 313 static osStatus yield();
elessair 0:f269e3021894 314
elessair 0:f269e3021894 315 /** Get the thread id of the current running thread.
elessair 0:f269e3021894 316 @return thread ID for reference by other functions or NULL in case of error.
elessair 0:f269e3021894 317 */
elessair 0:f269e3021894 318 static osThreadId gettid();
elessair 0:f269e3021894 319
elessair 0:f269e3021894 320 /** Attach a function to be called by the RTOS idle task
elessair 0:f269e3021894 321 @param fptr pointer to the function to be called
elessair 0:f269e3021894 322 */
elessair 0:f269e3021894 323 static void attach_idle_hook(void (*fptr)(void));
elessair 0:f269e3021894 324
elessair 0:f269e3021894 325 /** Attach a function to be called when a task is killed
elessair 0:f269e3021894 326 @param fptr pointer to the function to be called
elessair 0:f269e3021894 327 */
elessair 0:f269e3021894 328 static void attach_terminate_hook(void (*fptr)(osThreadId id));
elessair 0:f269e3021894 329
elessair 0:f269e3021894 330 virtual ~Thread();
elessair 0:f269e3021894 331
elessair 0:f269e3021894 332 private:
elessair 0:f269e3021894 333 // Required to share definitions without
elessair 0:f269e3021894 334 // delegated constructors
elessair 0:f269e3021894 335 void constructor(osPriority priority=osPriorityNormal,
elessair 0:f269e3021894 336 uint32_t stack_size=DEFAULT_STACK_SIZE,
elessair 0:f269e3021894 337 unsigned char *stack_pointer=NULL);
elessair 0:f269e3021894 338 void constructor(mbed::Callback<void()> task,
elessair 0:f269e3021894 339 osPriority priority=osPriorityNormal,
elessair 0:f269e3021894 340 uint32_t stack_size=DEFAULT_STACK_SIZE,
elessair 0:f269e3021894 341 unsigned char *stack_pointer=NULL);
elessair 0:f269e3021894 342 static void _thunk(const void * thread_ptr);
elessair 0:f269e3021894 343
elessair 0:f269e3021894 344 mbed::Callback<void()> _task;
elessair 0:f269e3021894 345 osThreadId _tid;
elessair 0:f269e3021894 346 osThreadDef_t _thread_def;
elessair 0:f269e3021894 347 bool _dynamic_stack;
elessair 0:f269e3021894 348 Semaphore _join_sem;
elessair 0:f269e3021894 349 Mutex _mutex;
elessair 0:f269e3021894 350 };
elessair 0:f269e3021894 351
elessair 0:f269e3021894 352 }
elessair 0:f269e3021894 353 #endif
elessair 0:f269e3021894 354
elessair 0:f269e3021894 355 /** @}*/