this hurts

Dependencies:   FFT

Committer:
annieluo2
Date:
Wed Dec 02 18:02:03 2020 +0000
Revision:
0:d6c9b09b4042
boo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
annieluo2 0:d6c9b09b4042 1 /* mbed Microcontroller Library
annieluo2 0:d6c9b09b4042 2 * Copyright (c) 2006-2012 ARM Limited
annieluo2 0:d6c9b09b4042 3 *
annieluo2 0:d6c9b09b4042 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
annieluo2 0:d6c9b09b4042 5 * of this software and associated documentation files (the "Software"), to deal
annieluo2 0:d6c9b09b4042 6 * in the Software without restriction, including without limitation the rights
annieluo2 0:d6c9b09b4042 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
annieluo2 0:d6c9b09b4042 8 * copies of the Software, and to permit persons to whom the Software is
annieluo2 0:d6c9b09b4042 9 * furnished to do so, subject to the following conditions:
annieluo2 0:d6c9b09b4042 10 *
annieluo2 0:d6c9b09b4042 11 * The above copyright notice and this permission notice shall be included in
annieluo2 0:d6c9b09b4042 12 * all copies or substantial portions of the Software.
annieluo2 0:d6c9b09b4042 13 *
annieluo2 0:d6c9b09b4042 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
annieluo2 0:d6c9b09b4042 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
annieluo2 0:d6c9b09b4042 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
annieluo2 0:d6c9b09b4042 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
annieluo2 0:d6c9b09b4042 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
annieluo2 0:d6c9b09b4042 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
annieluo2 0:d6c9b09b4042 20 * SOFTWARE.
annieluo2 0:d6c9b09b4042 21 */
annieluo2 0:d6c9b09b4042 22 #include "rtos/Thread.h"
annieluo2 0:d6c9b09b4042 23
annieluo2 0:d6c9b09b4042 24 #include "mbed.h"
annieluo2 0:d6c9b09b4042 25 #include "rtos/rtos_idle.h"
annieluo2 0:d6c9b09b4042 26
annieluo2 0:d6c9b09b4042 27 // rt_tid2ptcb is an internal function which we exposed to get TCB for thread id
annieluo2 0:d6c9b09b4042 28 #undef NULL //Workaround for conflicting macros in rt_TypeDef.h and stdio.h
annieluo2 0:d6c9b09b4042 29 #include "rt_TypeDef.h"
annieluo2 0:d6c9b09b4042 30
annieluo2 0:d6c9b09b4042 31 extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
annieluo2 0:d6c9b09b4042 32
annieluo2 0:d6c9b09b4042 33
annieluo2 0:d6c9b09b4042 34 static void (*terminate_hook)(osThreadId id) = 0;
annieluo2 0:d6c9b09b4042 35 extern "C" void thread_terminate_hook(osThreadId id)
annieluo2 0:d6c9b09b4042 36 {
annieluo2 0:d6c9b09b4042 37 if (terminate_hook != (void (*)(osThreadId))NULL) {
annieluo2 0:d6c9b09b4042 38 terminate_hook(id);
annieluo2 0:d6c9b09b4042 39 }
annieluo2 0:d6c9b09b4042 40 }
annieluo2 0:d6c9b09b4042 41
annieluo2 0:d6c9b09b4042 42 namespace rtos {
annieluo2 0:d6c9b09b4042 43
annieluo2 0:d6c9b09b4042 44 void Thread::constructor(osPriority priority,
annieluo2 0:d6c9b09b4042 45 uint32_t stack_size, unsigned char *stack_pointer) {
annieluo2 0:d6c9b09b4042 46 _tid = 0;
annieluo2 0:d6c9b09b4042 47 _dynamic_stack = (stack_pointer == NULL);
annieluo2 0:d6c9b09b4042 48
annieluo2 0:d6c9b09b4042 49 #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
annieluo2 0:d6c9b09b4042 50 _thread_def.tpriority = priority;
annieluo2 0:d6c9b09b4042 51 _thread_def.stacksize = stack_size;
annieluo2 0:d6c9b09b4042 52 _thread_def.stack_pointer = (uint32_t*)stack_pointer;
annieluo2 0:d6c9b09b4042 53 #endif
annieluo2 0:d6c9b09b4042 54 }
annieluo2 0:d6c9b09b4042 55
annieluo2 0:d6c9b09b4042 56 void Thread::constructor(Callback<void()> task,
annieluo2 0:d6c9b09b4042 57 osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
annieluo2 0:d6c9b09b4042 58 constructor(priority, stack_size, stack_pointer);
annieluo2 0:d6c9b09b4042 59
annieluo2 0:d6c9b09b4042 60 switch (start(task)) {
annieluo2 0:d6c9b09b4042 61 case osErrorResource:
annieluo2 0:d6c9b09b4042 62 error("OS ran out of threads!\n");
annieluo2 0:d6c9b09b4042 63 break;
annieluo2 0:d6c9b09b4042 64 case osErrorParameter:
annieluo2 0:d6c9b09b4042 65 error("Thread already running!\n");
annieluo2 0:d6c9b09b4042 66 break;
annieluo2 0:d6c9b09b4042 67 case osErrorNoMemory:
annieluo2 0:d6c9b09b4042 68 error("Error allocating the stack memory\n");
annieluo2 0:d6c9b09b4042 69 default:
annieluo2 0:d6c9b09b4042 70 break;
annieluo2 0:d6c9b09b4042 71 }
annieluo2 0:d6c9b09b4042 72 }
annieluo2 0:d6c9b09b4042 73
annieluo2 0:d6c9b09b4042 74 osStatus Thread::start(Callback<void()> task) {
annieluo2 0:d6c9b09b4042 75 _mutex.lock();
annieluo2 0:d6c9b09b4042 76
annieluo2 0:d6c9b09b4042 77 if (_tid != 0) {
annieluo2 0:d6c9b09b4042 78 _mutex.unlock();
annieluo2 0:d6c9b09b4042 79 return osErrorParameter;
annieluo2 0:d6c9b09b4042 80 }
annieluo2 0:d6c9b09b4042 81
annieluo2 0:d6c9b09b4042 82 #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
annieluo2 0:d6c9b09b4042 83 _thread_def.pthread = Thread::_thunk;
annieluo2 0:d6c9b09b4042 84 if (_thread_def.stack_pointer == NULL) {
annieluo2 0:d6c9b09b4042 85 _thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
annieluo2 0:d6c9b09b4042 86 MBED_ASSERT(_thread_def.stack_pointer != NULL);
annieluo2 0:d6c9b09b4042 87 }
annieluo2 0:d6c9b09b4042 88
annieluo2 0:d6c9b09b4042 89 //Fill the stack with a magic word for maximum usage checking
annieluo2 0:d6c9b09b4042 90 for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) {
annieluo2 0:d6c9b09b4042 91 _thread_def.stack_pointer[i] = 0xE25A2EA5;
annieluo2 0:d6c9b09b4042 92 }
annieluo2 0:d6c9b09b4042 93 #endif
annieluo2 0:d6c9b09b4042 94 _task = task;
annieluo2 0:d6c9b09b4042 95 _tid = osThreadCreate(&_thread_def, this);
annieluo2 0:d6c9b09b4042 96 if (_tid == NULL) {
annieluo2 0:d6c9b09b4042 97 if (_dynamic_stack) {
annieluo2 0:d6c9b09b4042 98 delete[] (_thread_def.stack_pointer);
annieluo2 0:d6c9b09b4042 99 _thread_def.stack_pointer = (uint32_t*)NULL;
annieluo2 0:d6c9b09b4042 100 }
annieluo2 0:d6c9b09b4042 101 _mutex.unlock();
annieluo2 0:d6c9b09b4042 102 _join_sem.release();
annieluo2 0:d6c9b09b4042 103 return osErrorResource;
annieluo2 0:d6c9b09b4042 104 }
annieluo2 0:d6c9b09b4042 105
annieluo2 0:d6c9b09b4042 106 _mutex.unlock();
annieluo2 0:d6c9b09b4042 107 return osOK;
annieluo2 0:d6c9b09b4042 108 }
annieluo2 0:d6c9b09b4042 109
annieluo2 0:d6c9b09b4042 110 osStatus Thread::terminate() {
annieluo2 0:d6c9b09b4042 111 osStatus ret;
annieluo2 0:d6c9b09b4042 112 _mutex.lock();
annieluo2 0:d6c9b09b4042 113
annieluo2 0:d6c9b09b4042 114 // Set the Thread's tid to NULL and
annieluo2 0:d6c9b09b4042 115 // release the semaphore before terminating
annieluo2 0:d6c9b09b4042 116 // since this thread could be terminating itself
annieluo2 0:d6c9b09b4042 117 osThreadId local_id = _tid;
annieluo2 0:d6c9b09b4042 118 _join_sem.release();
annieluo2 0:d6c9b09b4042 119 _tid = (osThreadId)NULL;
annieluo2 0:d6c9b09b4042 120
annieluo2 0:d6c9b09b4042 121 ret = osThreadTerminate(local_id);
annieluo2 0:d6c9b09b4042 122
annieluo2 0:d6c9b09b4042 123 _mutex.unlock();
annieluo2 0:d6c9b09b4042 124 return ret;
annieluo2 0:d6c9b09b4042 125 }
annieluo2 0:d6c9b09b4042 126
annieluo2 0:d6c9b09b4042 127 osStatus Thread::join() {
annieluo2 0:d6c9b09b4042 128 int32_t ret = _join_sem.wait();
annieluo2 0:d6c9b09b4042 129 if (ret < 0) {
annieluo2 0:d6c9b09b4042 130 return osErrorOS;
annieluo2 0:d6c9b09b4042 131 }
annieluo2 0:d6c9b09b4042 132
annieluo2 0:d6c9b09b4042 133 // The semaphore has been released so this thread is being
annieluo2 0:d6c9b09b4042 134 // terminated or has been terminated. Once the mutex has
annieluo2 0:d6c9b09b4042 135 // been locked it is ensured that the thread is deleted.
annieluo2 0:d6c9b09b4042 136 _mutex.lock();
annieluo2 0:d6c9b09b4042 137 MBED_ASSERT(NULL == _tid);
annieluo2 0:d6c9b09b4042 138 _mutex.unlock();
annieluo2 0:d6c9b09b4042 139
annieluo2 0:d6c9b09b4042 140 // Release sem so any other threads joining this thread wake up
annieluo2 0:d6c9b09b4042 141 _join_sem.release();
annieluo2 0:d6c9b09b4042 142 return osOK;
annieluo2 0:d6c9b09b4042 143 }
annieluo2 0:d6c9b09b4042 144
annieluo2 0:d6c9b09b4042 145 osStatus Thread::set_priority(osPriority priority) {
annieluo2 0:d6c9b09b4042 146 osStatus ret;
annieluo2 0:d6c9b09b4042 147 _mutex.lock();
annieluo2 0:d6c9b09b4042 148
annieluo2 0:d6c9b09b4042 149 ret = osThreadSetPriority(_tid, priority);
annieluo2 0:d6c9b09b4042 150
annieluo2 0:d6c9b09b4042 151 _mutex.unlock();
annieluo2 0:d6c9b09b4042 152 return ret;
annieluo2 0:d6c9b09b4042 153 }
annieluo2 0:d6c9b09b4042 154
annieluo2 0:d6c9b09b4042 155 osPriority Thread::get_priority() {
annieluo2 0:d6c9b09b4042 156 osPriority ret;
annieluo2 0:d6c9b09b4042 157 _mutex.lock();
annieluo2 0:d6c9b09b4042 158
annieluo2 0:d6c9b09b4042 159 ret = osThreadGetPriority(_tid);
annieluo2 0:d6c9b09b4042 160
annieluo2 0:d6c9b09b4042 161 _mutex.unlock();
annieluo2 0:d6c9b09b4042 162 return ret;
annieluo2 0:d6c9b09b4042 163 }
annieluo2 0:d6c9b09b4042 164
annieluo2 0:d6c9b09b4042 165 int32_t Thread::signal_set(int32_t signals) {
annieluo2 0:d6c9b09b4042 166 // osSignalSet is thread safe as long as the underlying
annieluo2 0:d6c9b09b4042 167 // thread does not get terminated or return from main
annieluo2 0:d6c9b09b4042 168 return osSignalSet(_tid, signals);
annieluo2 0:d6c9b09b4042 169 }
annieluo2 0:d6c9b09b4042 170
annieluo2 0:d6c9b09b4042 171 int32_t Thread::signal_clr(int32_t signals) {
annieluo2 0:d6c9b09b4042 172 // osSignalClear is thread safe as long as the underlying
annieluo2 0:d6c9b09b4042 173 // thread does not get terminated or return from main
annieluo2 0:d6c9b09b4042 174 return osSignalClear(_tid, signals);
annieluo2 0:d6c9b09b4042 175 }
annieluo2 0:d6c9b09b4042 176
annieluo2 0:d6c9b09b4042 177 Thread::State Thread::get_state() {
annieluo2 0:d6c9b09b4042 178 #if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM)
annieluo2 0:d6c9b09b4042 179 #ifdef CMSIS_OS_RTX
annieluo2 0:d6c9b09b4042 180 State status = Deleted;
annieluo2 0:d6c9b09b4042 181 _mutex.lock();
annieluo2 0:d6c9b09b4042 182
annieluo2 0:d6c9b09b4042 183 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 184 status = (State)_thread_def.tcb.state;
annieluo2 0:d6c9b09b4042 185 }
annieluo2 0:d6c9b09b4042 186
annieluo2 0:d6c9b09b4042 187 _mutex.unlock();
annieluo2 0:d6c9b09b4042 188 return status;
annieluo2 0:d6c9b09b4042 189 #endif
annieluo2 0:d6c9b09b4042 190 #else
annieluo2 0:d6c9b09b4042 191 State status = Deleted;
annieluo2 0:d6c9b09b4042 192 _mutex.lock();
annieluo2 0:d6c9b09b4042 193
annieluo2 0:d6c9b09b4042 194 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 195 status = (State)osThreadGetState(_tid);
annieluo2 0:d6c9b09b4042 196 }
annieluo2 0:d6c9b09b4042 197
annieluo2 0:d6c9b09b4042 198 _mutex.unlock();
annieluo2 0:d6c9b09b4042 199 return status;
annieluo2 0:d6c9b09b4042 200 #endif
annieluo2 0:d6c9b09b4042 201 }
annieluo2 0:d6c9b09b4042 202
annieluo2 0:d6c9b09b4042 203 uint32_t Thread::stack_size() {
annieluo2 0:d6c9b09b4042 204 #ifndef __MBED_CMSIS_RTOS_CA9
annieluo2 0:d6c9b09b4042 205 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
annieluo2 0:d6c9b09b4042 206 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 207 _mutex.lock();
annieluo2 0:d6c9b09b4042 208
annieluo2 0:d6c9b09b4042 209 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 210 size = _thread_def.tcb.priv_stack;
annieluo2 0:d6c9b09b4042 211 }
annieluo2 0:d6c9b09b4042 212
annieluo2 0:d6c9b09b4042 213 _mutex.unlock();
annieluo2 0:d6c9b09b4042 214 return size;
annieluo2 0:d6c9b09b4042 215 #else
annieluo2 0:d6c9b09b4042 216 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 217 _mutex.lock();
annieluo2 0:d6c9b09b4042 218
annieluo2 0:d6c9b09b4042 219 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 220 P_TCB tcb = rt_tid2ptcb(_tid);
annieluo2 0:d6c9b09b4042 221 size = tcb->priv_stack;
annieluo2 0:d6c9b09b4042 222 }
annieluo2 0:d6c9b09b4042 223
annieluo2 0:d6c9b09b4042 224 _mutex.unlock();
annieluo2 0:d6c9b09b4042 225 return size;
annieluo2 0:d6c9b09b4042 226 #endif
annieluo2 0:d6c9b09b4042 227 #else
annieluo2 0:d6c9b09b4042 228 return 0;
annieluo2 0:d6c9b09b4042 229 #endif
annieluo2 0:d6c9b09b4042 230 }
annieluo2 0:d6c9b09b4042 231
annieluo2 0:d6c9b09b4042 232 uint32_t Thread::free_stack() {
annieluo2 0:d6c9b09b4042 233 #ifndef __MBED_CMSIS_RTOS_CA9
annieluo2 0:d6c9b09b4042 234 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
annieluo2 0:d6c9b09b4042 235 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 236 _mutex.lock();
annieluo2 0:d6c9b09b4042 237
annieluo2 0:d6c9b09b4042 238 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 239 uint32_t bottom = (uint32_t)_thread_def.tcb.stack;
annieluo2 0:d6c9b09b4042 240 size = _thread_def.tcb.tsk_stack - bottom;
annieluo2 0:d6c9b09b4042 241 }
annieluo2 0:d6c9b09b4042 242
annieluo2 0:d6c9b09b4042 243 _mutex.unlock();
annieluo2 0:d6c9b09b4042 244 return size;
annieluo2 0:d6c9b09b4042 245 #else
annieluo2 0:d6c9b09b4042 246 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 247 _mutex.lock();
annieluo2 0:d6c9b09b4042 248
annieluo2 0:d6c9b09b4042 249 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 250 P_TCB tcb = rt_tid2ptcb(_tid);
annieluo2 0:d6c9b09b4042 251 uint32_t bottom = (uint32_t)tcb->stack;
annieluo2 0:d6c9b09b4042 252 size = tcb->tsk_stack - bottom;
annieluo2 0:d6c9b09b4042 253 }
annieluo2 0:d6c9b09b4042 254
annieluo2 0:d6c9b09b4042 255 _mutex.unlock();
annieluo2 0:d6c9b09b4042 256 return size;
annieluo2 0:d6c9b09b4042 257 #endif
annieluo2 0:d6c9b09b4042 258 #else
annieluo2 0:d6c9b09b4042 259 return 0;
annieluo2 0:d6c9b09b4042 260 #endif
annieluo2 0:d6c9b09b4042 261 }
annieluo2 0:d6c9b09b4042 262
annieluo2 0:d6c9b09b4042 263 uint32_t Thread::used_stack() {
annieluo2 0:d6c9b09b4042 264 #ifndef __MBED_CMSIS_RTOS_CA9
annieluo2 0:d6c9b09b4042 265 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
annieluo2 0:d6c9b09b4042 266 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 267 _mutex.lock();
annieluo2 0:d6c9b09b4042 268
annieluo2 0:d6c9b09b4042 269 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 270 uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack;
annieluo2 0:d6c9b09b4042 271 size = top - _thread_def.tcb.tsk_stack;
annieluo2 0:d6c9b09b4042 272 }
annieluo2 0:d6c9b09b4042 273
annieluo2 0:d6c9b09b4042 274 _mutex.unlock();
annieluo2 0:d6c9b09b4042 275 return size;
annieluo2 0:d6c9b09b4042 276 #else
annieluo2 0:d6c9b09b4042 277 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 278 _mutex.lock();
annieluo2 0:d6c9b09b4042 279
annieluo2 0:d6c9b09b4042 280 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 281 P_TCB tcb = rt_tid2ptcb(_tid);
annieluo2 0:d6c9b09b4042 282 uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack;
annieluo2 0:d6c9b09b4042 283 size = top - tcb->tsk_stack;
annieluo2 0:d6c9b09b4042 284 }
annieluo2 0:d6c9b09b4042 285
annieluo2 0:d6c9b09b4042 286 _mutex.unlock();
annieluo2 0:d6c9b09b4042 287 return size;
annieluo2 0:d6c9b09b4042 288 #endif
annieluo2 0:d6c9b09b4042 289 #else
annieluo2 0:d6c9b09b4042 290 return 0;
annieluo2 0:d6c9b09b4042 291 #endif
annieluo2 0:d6c9b09b4042 292 }
annieluo2 0:d6c9b09b4042 293
annieluo2 0:d6c9b09b4042 294 uint32_t Thread::max_stack() {
annieluo2 0:d6c9b09b4042 295 #ifndef __MBED_CMSIS_RTOS_CA9
annieluo2 0:d6c9b09b4042 296 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
annieluo2 0:d6c9b09b4042 297 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 298 _mutex.lock();
annieluo2 0:d6c9b09b4042 299
annieluo2 0:d6c9b09b4042 300 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 301 uint32_t high_mark = 0;
annieluo2 0:d6c9b09b4042 302 while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5)
annieluo2 0:d6c9b09b4042 303 high_mark++;
annieluo2 0:d6c9b09b4042 304 size = _thread_def.tcb.priv_stack - (high_mark * 4);
annieluo2 0:d6c9b09b4042 305 }
annieluo2 0:d6c9b09b4042 306
annieluo2 0:d6c9b09b4042 307 _mutex.unlock();
annieluo2 0:d6c9b09b4042 308 return size;
annieluo2 0:d6c9b09b4042 309 #else
annieluo2 0:d6c9b09b4042 310 uint32_t size = 0;
annieluo2 0:d6c9b09b4042 311 _mutex.lock();
annieluo2 0:d6c9b09b4042 312
annieluo2 0:d6c9b09b4042 313 if (_tid != NULL) {
annieluo2 0:d6c9b09b4042 314 P_TCB tcb = rt_tid2ptcb(_tid);
annieluo2 0:d6c9b09b4042 315 uint32_t high_mark = 0;
annieluo2 0:d6c9b09b4042 316 while (tcb->stack[high_mark] == 0xE25A2EA5)
annieluo2 0:d6c9b09b4042 317 high_mark++;
annieluo2 0:d6c9b09b4042 318 size = tcb->priv_stack - (high_mark * 4);
annieluo2 0:d6c9b09b4042 319 }
annieluo2 0:d6c9b09b4042 320
annieluo2 0:d6c9b09b4042 321 _mutex.unlock();
annieluo2 0:d6c9b09b4042 322 return size;
annieluo2 0:d6c9b09b4042 323 #endif
annieluo2 0:d6c9b09b4042 324 #else
annieluo2 0:d6c9b09b4042 325 return 0;
annieluo2 0:d6c9b09b4042 326 #endif
annieluo2 0:d6c9b09b4042 327 }
annieluo2 0:d6c9b09b4042 328
annieluo2 0:d6c9b09b4042 329 osEvent Thread::signal_wait(int32_t signals, uint32_t millisec) {
annieluo2 0:d6c9b09b4042 330 return osSignalWait(signals, millisec);
annieluo2 0:d6c9b09b4042 331 }
annieluo2 0:d6c9b09b4042 332
annieluo2 0:d6c9b09b4042 333 osStatus Thread::wait(uint32_t millisec) {
annieluo2 0:d6c9b09b4042 334 return osDelay(millisec);
annieluo2 0:d6c9b09b4042 335 }
annieluo2 0:d6c9b09b4042 336
annieluo2 0:d6c9b09b4042 337 osStatus Thread::yield() {
annieluo2 0:d6c9b09b4042 338 return osThreadYield();
annieluo2 0:d6c9b09b4042 339 }
annieluo2 0:d6c9b09b4042 340
annieluo2 0:d6c9b09b4042 341 osThreadId Thread::gettid() {
annieluo2 0:d6c9b09b4042 342 return osThreadGetId();
annieluo2 0:d6c9b09b4042 343 }
annieluo2 0:d6c9b09b4042 344
annieluo2 0:d6c9b09b4042 345 void Thread::attach_idle_hook(void (*fptr)(void)) {
annieluo2 0:d6c9b09b4042 346 rtos_attach_idle_hook(fptr);
annieluo2 0:d6c9b09b4042 347 }
annieluo2 0:d6c9b09b4042 348
annieluo2 0:d6c9b09b4042 349 void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) {
annieluo2 0:d6c9b09b4042 350 terminate_hook = fptr;
annieluo2 0:d6c9b09b4042 351 }
annieluo2 0:d6c9b09b4042 352
annieluo2 0:d6c9b09b4042 353 Thread::~Thread() {
annieluo2 0:d6c9b09b4042 354 // terminate is thread safe
annieluo2 0:d6c9b09b4042 355 terminate();
annieluo2 0:d6c9b09b4042 356 #ifdef __MBED_CMSIS_RTOS_CM
annieluo2 0:d6c9b09b4042 357 if (_dynamic_stack) {
annieluo2 0:d6c9b09b4042 358 delete[] (_thread_def.stack_pointer);
annieluo2 0:d6c9b09b4042 359 _thread_def.stack_pointer = (uint32_t*)NULL;
annieluo2 0:d6c9b09b4042 360 }
annieluo2 0:d6c9b09b4042 361 #endif
annieluo2 0:d6c9b09b4042 362 }
annieluo2 0:d6c9b09b4042 363
annieluo2 0:d6c9b09b4042 364 void Thread::_thunk(const void * thread_ptr)
annieluo2 0:d6c9b09b4042 365 {
annieluo2 0:d6c9b09b4042 366 Thread *t = (Thread*)thread_ptr;
annieluo2 0:d6c9b09b4042 367 t->_task();
annieluo2 0:d6c9b09b4042 368 t->_mutex.lock();
annieluo2 0:d6c9b09b4042 369 t->_tid = (osThreadId)NULL;
annieluo2 0:d6c9b09b4042 370 t->_join_sem.release();
annieluo2 0:d6c9b09b4042 371 // rtos will release the mutex automatically
annieluo2 0:d6c9b09b4042 372 }
annieluo2 0:d6c9b09b4042 373
annieluo2 0:d6c9b09b4042 374 }