mirror of https://github.com/ARMmbed/mbed-os.git
General block device test: Fix thread stack allocation
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. 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.pull/15059/head
parent
48cf1c9c80
commit
0b868d5a1a
|
@ -421,40 +421,35 @@ 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] {};
|
||||
|
||||
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];
|
||||
|
||||
if (!bd_thread[i_ind] || !dummy) {
|
||||
utest_printf("Not enough heap to run Thread %d !\n", i_ind + 1);
|
||||
if (!bd_thread[i_ind]) {
|
||||
utest_printf("Not enough heap to create Thread %d\n", i_ind + 1);
|
||||
break;
|
||||
}
|
||||
delete[] dummy;
|
||||
|
||||
threadStatus = bd_thread[i_ind]->start(callback(test_thread_job));
|
||||
if (threadStatus != 0) {
|
||||
utest_printf("Thread %d Start Failed!\n", i_ind + 1);
|
||||
if (threadStatus == osErrorNoMemory) {
|
||||
utest_printf("Not enough heap to start Thread %d\n", i_ind + 1);
|
||||
} else if (threadStatus != osOK) {
|
||||
utest_printf("Thread %d failed to start: %d\n", i_ind + 1, threadStatus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Join threads that successfully started
|
||||
for (j_ind = 0; j_ind < i_ind; j_ind++) {
|
||||
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;
|
||||
// Delete all threads, even those that failed to start
|
||||
for (j_ind = 0; j_ind < TEST_NUM_OF_THREADS; j_ind++) {
|
||||
delete bd_thread[j_ind];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue