mdot_rtos

Fork of mbed-rtos by mbed official

Revision:
119:6635230e06ba
Parent:
115:11950e007d8a
Child:
120:19af2d39a542
--- a/rtos/Thread.cpp	Mon May 23 11:00:15 2016 +0100
+++ b/rtos/Thread.cpp	Mon Jul 25 14:12:24 2016 +0100
@@ -21,7 +21,7 @@
  */
 #include "Thread.h"
 
-#include "mbed_error.h"
+#include "mbed.h"
 #include "rtos_idle.h"
 
 // rt_tid2ptcb is an internal function which we exposed to get TCB for thread id
@@ -32,34 +32,81 @@
 
 namespace rtos {
 
-Thread::Thread(void (*task)(void const *argument), void *argument,
-        osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
+void Thread::constructor(osPriority priority,
+        uint32_t stack_size, unsigned char *stack_pointer) {
+    _tid = 0;
+    _dynamic_stack = (stack_pointer == NULL);
+
 #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
-    _thread_def.pthread = task;
     _thread_def.tpriority = priority;
     _thread_def.stacksize = stack_size;
-    if (stack_pointer != NULL) {
-        _thread_def.stack_pointer = (uint32_t*)stack_pointer;
-        _dynamic_stack = false;
-    } else {
-        _thread_def.stack_pointer = new uint32_t[stack_size/sizeof(uint32_t)];
+    _thread_def.stack_pointer = (uint32_t*)stack_pointer;
+#endif
+}
+
+void Thread::constructor(Callback<void()> task,
+        osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
+    constructor(priority, stack_size, stack_pointer);
+
+    switch (start(task)) {
+        case osErrorResource:
+            error("OS ran out of threads!\n");
+            break;
+        case osErrorParameter:
+            error("Thread already running!\n");
+            break;
+        case osErrorNoMemory:
+            error("Error allocating the stack memory\n");
+        default:
+            break;
+    }
+}
+
+osStatus Thread::start(Callback<void()> task) {
+    if (_tid != 0) {
+        return osErrorParameter;
+    }
+
+#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
+    _thread_def.pthread = (void (*)(const void *))Callback<void()>::thunk;
+    if (_thread_def.stack_pointer == NULL) {
+        _thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
         if (_thread_def.stack_pointer == NULL)
-            error("Error allocating the stack memory\n");
-        _dynamic_stack = true;
+            return osErrorNoMemory;
     }
-    
+
     //Fill the stack with a magic word for maximum usage checking
-    for (uint32_t i = 0; i < (stack_size / sizeof(uint32_t)); i++) {
+    for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) {
         _thread_def.stack_pointer[i] = 0xE25A2EA5;
     }
 #endif
-    _tid = osThreadCreate(&_thread_def, argument);
+    _task = task;
+    _tid = osThreadCreate(&_thread_def, &_task);
+    if (_tid == NULL) {
+        if (_dynamic_stack) delete[] (_thread_def.stack_pointer);
+        return osErrorResource;
+    }
+    return osOK;
 }
 
 osStatus Thread::terminate() {
     return osThreadTerminate(_tid);
 }
 
+osStatus Thread::join() {
+    while (true) {
+        uint8_t state = get_state();
+        if (state == Thread::Inactive || state == osErrorParameter) {
+            return osOK;
+        }
+
+        osStatus status = yield();
+        if (status != osOK) {
+            return status;
+        }
+    }
+}
+
 osStatus Thread::set_priority(osPriority priority) {
     return osThreadSetPriority(_tid, priority);
 }