[FL-3289] Various Furi/FuriHal bug fixes and improvements (#2637)

* Furi: properly handle thread free before TCB scrapping, add furi_free - more invasive version of free to memmgr. FuriHal: add DWT comparator api to cortex. Updater, RPC: refactor various thread shanenigans. Code cleanup.
* Rollback free macros and related changes
This commit is contained in:
あく
2023-05-05 21:40:55 +09:00
committed by GitHub
parent a7d1ec03e8
commit 914129a0d9
15 changed files with 204 additions and 70 deletions
+16 -14
View File
@@ -164,10 +164,13 @@ FuriThread* furi_thread_alloc_ex(
void furi_thread_free(FuriThread* thread) {
furi_assert(thread);
furi_assert(thread->state == FuriThreadStateStopped);
if(thread->name) free((void*)thread->name);
if(thread->appid) free((void*)thread->appid);
// Ensure that use join before free
furi_assert(thread->state == FuriThreadStateStopped);
furi_assert(thread->task_handle == NULL);
if(thread->name) free(thread->name);
if(thread->appid) free(thread->appid);
furi_string_free(thread->output.buffer);
free(thread);
@@ -176,14 +179,14 @@ void furi_thread_free(FuriThread* thread) {
void furi_thread_set_name(FuriThread* thread, const char* name) {
furi_assert(thread);
furi_assert(thread->state == FuriThreadStateStopped);
if(thread->name) free((void*)thread->name);
if(thread->name) free(thread->name);
thread->name = name ? strdup(name) : NULL;
}
void furi_thread_set_appid(FuriThread* thread, const char* appid) {
furi_assert(thread);
furi_assert(thread->state == FuriThreadStateStopped);
if(thread->appid) free((void*)thread->appid);
if(thread->appid) free(thread->appid);
thread->appid = appid ? strdup(appid) : NULL;
}
@@ -276,7 +279,7 @@ void furi_thread_cleanup_tcb_event(TaskHandle_t task) {
if(thread) {
// clear thread local storage
vTaskSetThreadLocalStoragePointer(task, 0, NULL);
furi_assert(thread->task_handle == task);
thread->task_handle = NULL;
}
}
@@ -332,7 +335,6 @@ FuriThreadId furi_thread_get_current_id() {
FuriThread* furi_thread_get_current() {
FuriThread* thread = pvTaskGetThreadLocalStoragePointer(NULL, 0);
furi_assert(thread != NULL);
return thread;
}
@@ -579,24 +581,22 @@ static int32_t __furi_thread_stdout_flush(FuriThread* thread) {
return 0;
}
bool furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback) {
void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback) {
FuriThread* thread = furi_thread_get_current();
furi_assert(thread);
__furi_thread_stdout_flush(thread);
thread->output.write_callback = callback;
return true;
}
FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback() {
FuriThread* thread = furi_thread_get_current();
furi_assert(thread);
return thread->output.write_callback;
}
size_t furi_thread_stdout_write(const char* data, size_t size) {
FuriThread* thread = furi_thread_get_current();
furi_assert(thread);
if(size == 0 || data == NULL) {
return __furi_thread_stdout_flush(thread);
} else {
@@ -619,7 +619,9 @@ size_t furi_thread_stdout_write(const char* data, size_t size) {
}
int32_t furi_thread_stdout_flush() {
return __furi_thread_stdout_flush(furi_thread_get_current());
FuriThread* thread = furi_thread_get_current();
furi_assert(thread);
return __furi_thread_stdout_flush(thread);
}
void furi_thread_suspend(FuriThreadId thread_id) {
+3 -5
View File
@@ -233,7 +233,7 @@ FuriThreadId furi_thread_get_current_id();
/** Get FuriThread instance for current thread
*
* @return FuriThread*
* @return pointer to FuriThread or NULL if this thread doesn't belongs to Furi
*/
FuriThread* furi_thread_get_current();
@@ -288,12 +288,10 @@ uint32_t furi_thread_get_stack_space(FuriThreadId thread_id);
FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback();
/** Set STDOUT callback for thread
*
*
* @param callback callback or NULL to clear
*
* @return true on success, otherwise fail
*/
bool furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback);
void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback);
/** Write data to buffered STDOUT
*
+10
View File
@@ -124,3 +124,13 @@ uint32_t furi_timer_is_running(FuriTimer* instance) {
/* Return 0: not running, 1: running */
return (uint32_t)xTimerIsTimerActive(hTimer);
}
void furi_timer_pending_callback(FuriTimerPendigCallback callback, void* context, uint32_t arg) {
BaseType_t ret = pdFAIL;
if(furi_kernel_is_irq_or_masked()) {
ret = xTimerPendFunctionCallFromISR(callback, context, arg, NULL);
} else {
ret = xTimerPendFunctionCall(callback, context, arg, FuriWaitForever);
}
furi_check(ret == pdPASS);
}
+4
View File
@@ -56,6 +56,10 @@ FuriStatus furi_timer_stop(FuriTimer* instance);
*/
uint32_t furi_timer_is_running(FuriTimer* instance);
typedef void (*FuriTimerPendigCallback)(void* context, uint32_t arg);
void furi_timer_pending_callback(FuriTimerPendigCallback callback, void* context, uint32_t arg);
#ifdef __cplusplus
}
#endif