Skip to content

Commit

Permalink
rtos: Thread: Make stack allocation failure runtime catchable
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
LDong-Arm committed Sep 8, 2021
1 parent d1f02f3 commit 48cf1c9
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 3 deletions.
3 changes: 2 additions & 1 deletion rtos/include/rtos/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ class Thread : private mbed::NonCopyable<Thread> {

/** Starts a thread executing the specified function.
@param task function to be executed by this thread.
@return status code that indicates the execution status of the function.
@return status code that indicates the execution status of the function,
or osErrorNoMemory if stack allocation failed.
@note a thread can only be started once
@note You cannot call this function ISR context.
Expand Down
7 changes: 5 additions & 2 deletions rtos/source/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,11 @@ osStatus Thread::start(mbed::Callback<void()> task)
}

if (_attr.stack_mem == nullptr) {
_attr.stack_mem = new uint32_t[_attr.stack_size / sizeof(uint32_t)];
MBED_ASSERT(_attr.stack_mem != nullptr);
_attr.stack_mem = new (std::nothrow) uint32_t[_attr.stack_size / sizeof(uint32_t)];
if (_attr.stack_mem == nullptr) {
_mutex.unlock();
return osErrorNoMemory;
}
}

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

0 comments on commit 48cf1c9

Please sign in to comment.