Skip to content

Commit 2db84da

Browse files
committed
Merge pull request #1785 from geky/thread-lifetime
Add lifetime management to threads
2 parents 974ecf7 + 57bc433 commit 2db84da

File tree

2 files changed

+84
-11
lines changed

2 files changed

+84
-11
lines changed

rtos/rtos/Thread.cpp

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,82 @@ extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
3232

3333
namespace rtos {
3434

35+
Thread::Thread(osPriority priority,
36+
uint32_t stack_size, unsigned char *stack_pointer):
37+
_tid(0), _dynamic_stack(stack_pointer == NULL) {
38+
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
39+
_thread_def.tpriority = priority;
40+
_thread_def.stacksize = stack_size;
41+
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
42+
#endif
43+
}
44+
3545
Thread::Thread(void (*task)(void const *argument), void *argument,
36-
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
46+
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer):
47+
_tid(0), _dynamic_stack(stack_pointer == NULL) {
3748
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
38-
_thread_def.pthread = task;
3949
_thread_def.tpriority = priority;
4050
_thread_def.stacksize = stack_size;
41-
if (stack_pointer != NULL) {
42-
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
43-
_dynamic_stack = false;
44-
} else {
45-
_thread_def.stack_pointer = new uint32_t[stack_size/sizeof(uint32_t)];
46-
if (_thread_def.stack_pointer == NULL)
51+
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
52+
#endif
53+
switch (start(task, argument)) {
54+
case osErrorResource:
55+
error("OS ran out of threads!\n");
56+
break;
57+
case osErrorParameter:
58+
error("Thread already running!\n");
59+
break;
60+
case osErrorNoMemory:
4761
error("Error allocating the stack memory\n");
48-
_dynamic_stack = true;
62+
default:
63+
break;
64+
}
65+
}
66+
67+
osStatus Thread::start(void (*task)(void const *argument), void *argument) {
68+
if (_tid != NULL) {
69+
return osErrorParameter;
4970
}
50-
71+
72+
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
73+
_thread_def.pthread = task;
74+
if (_thread_def.stack_pointer == NULL) {
75+
_thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
76+
if (_thread_def.stack_pointer == NULL)
77+
return osErrorNoMemory;
78+
}
79+
5180
//Fill the stack with a magic word for maximum usage checking
52-
for (uint32_t i = 0; i < (stack_size / sizeof(uint32_t)); i++) {
81+
for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) {
5382
_thread_def.stack_pointer[i] = 0xE25A2EA5;
5483
}
5584
#endif
5685
_tid = osThreadCreate(&_thread_def, argument);
86+
if (_tid == NULL) {
87+
if (_dynamic_stack) delete[] (_thread_def.stack_pointer);
88+
return osErrorResource;
89+
}
90+
return osOK;
5791
}
5892

5993
osStatus Thread::terminate() {
6094
return osThreadTerminate(_tid);
6195
}
6296

97+
osStatus Thread::join() {
98+
while (true) {
99+
uint8_t state = get_state();
100+
if (state == Thread::Inactive || state == osErrorParameter) {
101+
return osOK;
102+
}
103+
104+
osStatus status = yield();
105+
if (status != osOK) {
106+
return status;
107+
}
108+
}
109+
}
110+
63111
osStatus Thread::set_priority(osPriority priority) {
64112
return osThreadSetPriority(_tid, priority);
65113
}

rtos/rtos/Thread.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ namespace rtos {
3030
/** The Thread class allow defining, creating, and controlling thread functions in the system. */
3131
class Thread {
3232
public:
33+
/** Allocate a new thread without starting execution
34+
@param priority initial priority of the thread function. (default: osPriorityNormal).
35+
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
36+
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
37+
*/
38+
Thread(osPriority priority=osPriorityNormal,
39+
uint32_t stack_size=DEFAULT_STACK_SIZE,
40+
unsigned char *stack_pointer=NULL);
41+
3342
/** Create a new thread, and start it executing the specified function.
3443
@param task function to be executed by this thread.
3544
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
@@ -42,6 +51,19 @@ class Thread {
4251
uint32_t stack_size=DEFAULT_STACK_SIZE,
4352
unsigned char *stack_pointer=NULL);
4453

54+
/** Starts a thread executing the specified function.
55+
@param task function to be executed by this thread.
56+
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
57+
@return status code that indicates the execution status of the function.
58+
*/
59+
osStatus start(void (*task)(void const *argument), void *argument=NULL);
60+
61+
/** Wait for thread to terminate
62+
@return status code that indicates the execution status of the function.
63+
@note not callable from interrupt
64+
*/
65+
osStatus join();
66+
4567
/** Terminate execution of a thread and remove it from Active Threads
4668
@return status code that indicates the execution status of the function.
4769
*/
@@ -113,17 +135,20 @@ class Thread {
113135
@param signals wait until all specified signal flags set or 0 for any single signal flag.
114136
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
115137
@return event flag information or error code.
138+
@note not callable from interrupt
116139
*/
117140
static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
118141

119142
/** Wait for a specified time period in millisec:
120143
@param millisec time delay value
121144
@return status code that indicates the execution status of the function.
145+
@note not callable from interrupt
122146
*/
123147
static osStatus wait(uint32_t millisec);
124148

125149
/** Pass control to next thread that is in state READY.
126150
@return status code that indicates the execution status of the function.
151+
@note not callable from interrupt
127152
*/
128153
static osStatus yield();
129154

0 commit comments

Comments
 (0)