Skip to content

Commit

Permalink
General block device test: Fix thread stack allocation
Browse files Browse the repository at this point in the history
The test case for multithreaded erase/program/read allocates a few
Thread objects from the heap and starts them. It has a few problems:

* To check that there will be enough heap to start a new thread, the
test case tries to allocate a dummy buffer of the thread's heap size
and then frees it, before starting the thread. Then the thread will
allocate its own stack. Such check is not reliable, because threads
that are already running also perform additional allocation (when
running `test_thread_job()`) and may take away the memory we just
checked.
* When deleting all threads in a loop, the loop boundary misses the
last thread if the last thread object was allocated but not started
(i.e. due to failed thread stack allocation check).

To fix the issues
* Start a thread without any allocation test (which is unreliable).
Following the preceding commit "rtos: Thread: Make stack allocation
failure runtime catchable", `Thread::start()` now returns
`osErrorNoMemory` if stack allocation fails which we can handle.
* Store pointers to all threads in a zero-initialized array, and
free all elements at the end of the test.
  • Loading branch information
LDong-Arm committed Sep 8, 2021
1 parent 2640f9d commit c16cc35
Showing 1 changed file with 8 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -421,22 +421,19 @@ void test_multi_threads()

osStatus threadStatus;
int i_ind, j_ind;
char *dummy;

rtos::Thread **bd_thread = new (std::nothrow) rtos::Thread*[TEST_NUM_OF_THREADS];
TEST_SKIP_UNLESS_MESSAGE((*bd_thread) != NULL, "not enough heap to run test.");
memset(bd_thread, 0, TEST_NUM_OF_THREADS * sizeof(rtos::Thread *));
rtos::Thread *bd_thread[TEST_NUM_OF_THREADS] {};
unsigned char *stack[TEST_NUM_OF_THREADS] {};

for (i_ind = 0; i_ind < TEST_NUM_OF_THREADS; i_ind++) {

bd_thread[i_ind] = new (std::nothrow) rtos::Thread((osPriority_t)((int)osPriorityNormal), TEST_THREAD_STACK_SIZE);
dummy = new (std::nothrow) char[TEST_THREAD_STACK_SIZE];
stack[i_ind] = new (std::nothrow) unsigned char[TEST_THREAD_STACK_SIZE];
bd_thread[i_ind] = new (std::nothrow) rtos::Thread((osPriority_t)((int)osPriorityNormal), TEST_THREAD_STACK_SIZE, stack[i_ind]);

if (!bd_thread[i_ind] || !dummy) {
if (!bd_thread[i_ind] || !stack[i_ind]) {
utest_printf("Not enough heap to run Thread %d !\n", i_ind + 1);
break;
}
delete[] dummy;

threadStatus = bd_thread[i_ind]->start(callback(test_thread_job));
if (threadStatus != 0) {
Expand All @@ -449,12 +446,9 @@ void test_multi_threads()
bd_thread[j_ind]->join();
}

if (bd_thread) {
for (j_ind = 0; j_ind < i_ind; j_ind++) {
delete bd_thread[j_ind];
}

delete[] bd_thread;
for (j_ind = 0; j_ind < TEST_NUM_OF_THREADS; j_ind++) {
delete bd_thread[j_ind];
delete[] stack[j_ind];
}
}
#endif
Expand Down

0 comments on commit c16cc35

Please sign in to comment.