diff --git a/core/mbed-rtos/rtos/Thread.cpp b/core/mbed-rtos/rtos/Thread.cpp index 402295e8d7..61e533a521 100644 --- a/core/mbed-rtos/rtos/Thread.cpp +++ b/core/mbed-rtos/rtos/Thread.cpp @@ -21,14 +21,16 @@ */ #include "Thread.h" -#include "mbed_error.h" +#include "mbed.h" #include "rtos_idle.h" namespace rtos { -Thread::Thread(osPriority priority, - uint32_t stack_size, unsigned char *stack_pointer): - _tid(NULL), _dynamic_stack(stack_pointer == NULL) { +void Thread::constructor(osPriority priority, + uint32_t stack_size, unsigned char *stack_pointer) { + _tid = NULL; + _dynamic_stack = (stack_pointer == NULL); + #ifdef __MBED_CMSIS_RTOS_CM _thread_def.tpriority = priority; _thread_def.stacksize = stack_size; @@ -36,15 +38,17 @@ Thread::Thread(osPriority priority, #endif } -Thread::Thread(void (*task)(void const *argument), void *argument, - osPriority priority, uint32_t stack_size, unsigned char *stack_pointer): - _tid(NULL), _dynamic_stack(stack_pointer == NULL) { +void Thread::constructor(Callback task, + osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) { + _tid = NULL; + _dynamic_stack = (stack_pointer == NULL); + #ifdef __MBED_CMSIS_RTOS_CM _thread_def.tpriority = priority; _thread_def.stacksize = stack_size; _thread_def.stack_pointer = (uint32_t*)stack_pointer; #endif - switch(start(task, argument)) { + switch(start(task)) { case osErrorResource: error("OS ran out of threads!\n"); break; @@ -58,13 +62,13 @@ Thread::Thread(void (*task)(void const *argument), void *argument, } } -osStatus Thread::start(void (*task)(void const *argument), void *argument) { +osStatus Thread::start(Callback task) { if (_tid != NULL) { return osErrorParameter; } #ifdef __MBED_CMSIS_RTOS_CM - _thread_def.pthread = task; + _thread_def.pthread = (void (*)(const void *))Callback::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) @@ -76,7 +80,8 @@ osStatus Thread::start(void (*task)(void const *argument), void *argument) { _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; diff --git a/core/mbed-rtos/rtos/Thread.h b/core/mbed-rtos/rtos/Thread.h index 275f6fe5c9..f28706d465 100644 --- a/core/mbed-rtos/rtos/Thread.h +++ b/core/mbed-rtos/rtos/Thread.h @@ -24,6 +24,7 @@ #include #include "cmsis_os.h" +#include "Callback.h" namespace rtos { @@ -37,26 +38,87 @@ public: */ Thread(osPriority priority=osPriorityNormal, uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL); + unsigned char *stack_pointer=NULL) { + constructor(priority, stack_size, stack_pointer); + } /** Create a new thread, and start it executing the specified function. @param task function to be executed by this thread. - @param argument pointer that is passed to the thread function as start argument. (default: NULL). @param priority initial priority of the thread function. (default: osPriorityNormal). @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). */ + Thread(mbed::Callback task, + osPriority priority=osPriorityNormal, + uint32_t stack_size=DEFAULT_STACK_SIZE, + unsigned char *stack_pointer=NULL) { + constructor(task, priority, stack_size, stack_pointer); + } + + /** Create a new thread, and start it executing the specified function. + @param obj argument to task. + @param method function to be executed by this thread. + @param priority initial priority of the thread function. (default: osPriorityNormal). + @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). + @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + */ + template + Thread(T *obj, void (T::*method)(), + osPriority priority=osPriorityNormal, + uint32_t stack_size=DEFAULT_STACK_SIZE, + unsigned char *stack_pointer=NULL) { + constructor(mbed::Callback(obj, method), + priority, stack_size, stack_pointer); + } + + /** Create a new thread, and start it executing the specified function. + @param obj argument to task. + @param method function to be executed by this thread. + @param priority initial priority of the thread function. (default: osPriorityNormal). + @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). + @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + */ + template + Thread(T *obj, void (*method)(T *), + osPriority priority=osPriorityNormal, + uint32_t stack_size=DEFAULT_STACK_SIZE, + unsigned char *stack_pointer=NULL) { + constructor(mbed::Callback(obj, method), + priority, stack_size, stack_pointer); + } + + /** Create a new thread, and start it executing the specified function. + Provided for backwards compatibility + @param task function to be executed by this thread. + @param argument pointer that is passed to the thread function as start argument. (default: NULL). + @param priority initial priority OF the thread function. (default: osPriorityNormal). + @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). + @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + */ Thread(void (*task)(void const *argument), void *argument=NULL, osPriority priority=osPriorityNormal, uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL); + unsigned char *stack_pointer=NULL) { + constructor(mbed::Callback(argument, (void (*)(void *))task), + priority, stack_size, stack_pointer); + } /** Starts a thread executing the specified function. @param task function to be executed by this thread. @param argument pointer that is passed to the thread function as start argument. (default: NULL). @return status code that indicates the execution status of the function. */ - osStatus start(void (*task)(void const *argument), void *argument=NULL); + osStatus start(mbed::Callback task); + + /** Starts a thread executing the specified function. + @param obj argument to task. + @param method function to be executed by this thread. + @return status code that indicates the execution status of the function. + */ + template + osStatus start(T *obj, M method) { + return start(mbed::Callback(obj, method)); + } /** Wait for thread to terminate @return status code that indicates the execution status of the function. @@ -165,6 +227,17 @@ public: virtual ~Thread(); private: + // Required to share definitions without without + // delegated constructors + void constructor(osPriority priority=osPriorityNormal, + uint32_t stack_size=DEFAULT_STACK_SIZE, + unsigned char *stack_pointer=NULL); + void constructor(mbed::Callback task, + osPriority priority=osPriorityNormal, + uint32_t stack_size=DEFAULT_STACK_SIZE, + unsigned char *stack_pointer=NULL); + + mbed::Callback _task; osThreadId _tid; osThreadDef_t _thread_def; bool _dynamic_stack;