Improved thread lifecycle (#2534)

* Core, Thread: mark thread to join from prvDeleteTCB
* USB HAL: move vars to MEM2
* Core, Thread: cleanup sources
* Cli: add magic delays on rx pipe error, prevent cli from consuming processor time
* Furi: update thread documentation

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Sergey Gavrilov
2023-03-28 00:34:49 -07:00
committed by GitHub
parent 3617ad33e4
commit 8b2dfea925
6 changed files with 39 additions and 17 deletions

View File

@@ -24,7 +24,6 @@ struct FuriThreadStdout {
};
struct FuriThread {
bool is_service;
FuriThreadState state;
int32_t ret;
@@ -37,14 +36,19 @@ struct FuriThread {
char* name;
char* appid;
configSTACK_DEPTH_TYPE stack_size;
FuriThreadPriority priority;
TaskHandle_t task_handle;
bool heap_trace_enabled;
size_t heap_size;
FuriThreadStdout output;
// Keep all non-alignable byte types in one place,
// this ensures that the size of this structure is minimal
bool is_service;
bool heap_trace_enabled;
configSTACK_DEPTH_TYPE stack_size;
};
static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size);
@@ -107,14 +111,8 @@ static void furi_thread_body(void* context) {
// flush stdout
__furi_thread_stdout_flush(thread);
// from here we can't use thread pointer
furi_thread_set_state(thread, FuriThreadStateStopped);
// clear thread local storage
furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) != NULL);
vTaskSetThreadLocalStoragePointer(NULL, 0, NULL);
thread->task_handle = NULL;
vTaskDelete(NULL);
furi_thread_catch();
}
@@ -249,11 +247,11 @@ void furi_thread_start(FuriThread* thread) {
furi_assert(thread);
furi_assert(thread->callback);
furi_assert(thread->state == FuriThreadStateStopped);
furi_assert(thread->stack_size > 0 && thread->stack_size < 0xFFFF * 4);
furi_assert(thread->stack_size > 0 && thread->stack_size < (UINT16_MAX * sizeof(StackType_t)));
furi_thread_set_state(thread, FuriThreadStateStarting);
uint32_t stack = thread->stack_size / 4;
uint32_t stack = thread->stack_size / sizeof(StackType_t);
UBaseType_t priority = thread->priority ? thread->priority : FuriThreadPriorityNormal;
if(thread->is_service) {
thread->task_handle = xTaskCreateStatic(
@@ -273,12 +271,25 @@ void furi_thread_start(FuriThread* thread) {
furi_check(thread->task_handle);
}
void furi_thread_cleanup_tcb_event(TaskHandle_t task) {
FuriThread* thread = pvTaskGetThreadLocalStoragePointer(task, 0);
if(thread) {
// clear thread local storage
vTaskSetThreadLocalStoragePointer(task, 0, NULL);
thread->task_handle = NULL;
}
}
bool furi_thread_join(FuriThread* thread) {
furi_assert(thread);
furi_check(furi_thread_get_current() != thread);
// Wait for thread to stop
// !!! IMPORTANT NOTICE !!!
//
// If your thread exited, but your app stuck here: some other thread uses
// all cpu time, which delays kernel from releasing task handle
while(thread->task_handle) {
furi_delay_ms(10);
}

View File

@@ -75,6 +75,8 @@ FuriThread* furi_thread_alloc_ex(
void* context);
/** Release FuriThread
*
* @warning see furi_thread_join
*
* @param thread FuriThread instance
*/
@@ -173,6 +175,9 @@ FuriThreadState furi_thread_get_state(FuriThread* thread);
void furi_thread_start(FuriThread* thread);
/** Join FuriThread
*
* @warning Use this method only when CPU is not busy(Idle task receives
* control), otherwise it will wait forever.
*
* @param thread FuriThread instance
*

View File

@@ -54,8 +54,8 @@ void vApplicationGetIdleTaskMemory(
StackType_t** stack_ptr,
uint32_t* stack_size) {
*tcb_ptr = memmgr_alloc_from_pool(sizeof(StaticTask_t));
*stack_ptr = memmgr_alloc_from_pool(sizeof(StackType_t) * configMINIMAL_STACK_SIZE);
*stack_size = configMINIMAL_STACK_SIZE;
*stack_ptr = memmgr_alloc_from_pool(sizeof(StackType_t) * configIDLE_TASK_STACK_DEPTH);
*stack_size = configIDLE_TASK_STACK_DEPTH;
}
void vApplicationGetTimerTaskMemory(