Skip to content

Commit 48cf1c9

Browse files
committed
rtos: Thread: Make stack allocation failure runtime catchable
When a Thread object's stack memory is not provided, its `start()` member function dynamically allocates its stack from the heap. If allocation fails, there is no way to catch it because * `std::nothrow` is missing after the `new` keyword. As Mbed OS is built with `-fno-exceptions` (C++ exceptions disabled), failed allocation results in an unrecoverable fault. * The attempted `nullptr` check, which doesn't work anyway due to the first point, is an assertion instead of error returning. Assertions should be used as a development tool to ensure code behaves correctly. But out-of-memory is a completely valid runtime situation. This commit adds the missing `std::nothrow`, and makes `Thread::start()` return `osErrorNoMemory` if allocation fails so the caller can handle it. Note: A case when a thread should never fail due to lack of memory is the main thread. But the main thread's stack is a pre-allocated array in the static memory, passed to the `Thread()` constructor during thread creation, so it's not impacted by this change.
1 parent d1f02f3 commit 48cf1c9

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

rtos/include/rtos/Thread.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ class Thread : private mbed::NonCopyable<Thread> {
131131

132132
/** Starts a thread executing the specified function.
133133
@param task function to be executed by this thread.
134-
@return status code that indicates the execution status of the function.
134+
@return status code that indicates the execution status of the function,
135+
or osErrorNoMemory if stack allocation failed.
135136
@note a thread can only be started once
136137
137138
@note You cannot call this function ISR context.

rtos/source/Thread.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,11 @@ osStatus Thread::start(mbed::Callback<void()> task)
8181
}
8282

8383
if (_attr.stack_mem == nullptr) {
84-
_attr.stack_mem = new uint32_t[_attr.stack_size / sizeof(uint32_t)];
85-
MBED_ASSERT(_attr.stack_mem != nullptr);
84+
_attr.stack_mem = new (std::nothrow) uint32_t[_attr.stack_size / sizeof(uint32_t)];
85+
if (_attr.stack_mem == nullptr) {
86+
_mutex.unlock();
87+
return osErrorNoMemory;
88+
}
8689
}
8790

8891
//Fill the stack with a magic word for maximum usage checking

0 commit comments

Comments
 (0)