[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
+1
View File
@@ -248,6 +248,7 @@ static void loader_do_app_closed(Loader* loader) {
free(loader->app.name);
loader->app.name = NULL;
furi_thread_join(loader->app.thread);
furi_thread_free(loader->app.thread);
loader->app.thread = NULL;
}
+27 -23
View File
@@ -326,31 +326,35 @@ static int32_t rpc_session_worker(void* context) {
return 0;
}
static void rpc_session_free_callback(FuriThreadState thread_state, void* context) {
furi_assert(context);
static void rpc_session_thread_pending_callback(void* context, uint32_t arg) {
UNUSED(arg);
RpcSession* session = (RpcSession*)context;
for(size_t i = 0; i < COUNT_OF(rpc_systems); ++i) {
if(rpc_systems[i].free) {
(rpc_systems[i].free)(session->system_contexts[i]);
}
}
free(session->system_contexts);
free(session->decoded_message);
RpcHandlerDict_clear(session->handlers);
furi_stream_buffer_free(session->stream);
furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever);
if(session->terminated_callback) {
session->terminated_callback(session->context);
}
furi_mutex_release(session->callbacks_mutex);
furi_mutex_free(session->callbacks_mutex);
furi_thread_join(session->thread);
furi_thread_free(session->thread);
free(session);
}
static void rpc_session_thread_state_callback(FuriThreadState thread_state, void* context) {
if(thread_state == FuriThreadStateStopped) {
for(size_t i = 0; i < COUNT_OF(rpc_systems); ++i) {
if(rpc_systems[i].free) {
rpc_systems[i].free(session->system_contexts[i]);
}
}
free(session->system_contexts);
free(session->decoded_message);
RpcHandlerDict_clear(session->handlers);
furi_stream_buffer_free(session->stream);
furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever);
if(session->terminated_callback) {
session->terminated_callback(session->context);
}
furi_mutex_release(session->callbacks_mutex);
furi_mutex_free(session->callbacks_mutex);
furi_thread_free(session->thread);
free(session);
furi_timer_pending_callback(rpc_session_thread_pending_callback, context, 0);
}
}
@@ -385,7 +389,7 @@ RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner) {
session->thread = furi_thread_alloc_ex("RpcSessionWorker", 3072, rpc_session_worker, session);
furi_thread_set_state_context(session->thread, session);
furi_thread_set_state_callback(session->thread, rpc_session_free_callback);
furi_thread_set_state_callback(session->thread, rpc_session_thread_state_callback);
furi_thread_start(session->thread);
@@ -803,6 +803,7 @@ void storage_file_free(File* file) {
}
FuriPubSub* storage_get_pubsub(Storage* storage) {
furi_assert(storage);
return storage->pubsub;
}
@@ -337,6 +337,7 @@ static bool storage_ext_file_close(void* ctx, File* file) {
file->internal_error_id = f_close(file_data);
file->error_id = storage_ext_parse_error(file->internal_error_id);
free(file_data);
storage_set_storage_file_data(file, NULL, storage);
return (file->error_id == FSE_OK);
}
@@ -53,7 +53,9 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
(uint32_t)(data->vbus_voltage),
(uint32_t)(data->vbus_voltage * 10) % 10,
current);
} else if(current < 0) {
} else if(current < -5) {
// Often gauge reports anything in the range 1~5ma as 5ma
// That brings confusion, so we'll treat it as Napping
snprintf(
emote,
sizeof(emote),
+6 -20
View File
@@ -85,22 +85,10 @@ static void updater_cli_ep(Cli* cli, FuriString* args, void* context) {
updater_cli_help(args);
}
static int32_t updater_spawner_thread_worker(void* arg) {
static void updater_start_app(void* context, uint32_t arg) {
UNUSED(context);
UNUSED(arg);
Loader* loader = furi_record_open(RECORD_LOADER);
loader_start(loader, "UpdaterApp", NULL);
furi_record_close(RECORD_LOADER);
return 0;
}
static void updater_spawner_thread_cleanup(FuriThreadState state, void* context) {
FuriThread* thread = context;
if(state == FuriThreadStateStopped) {
furi_thread_free(thread);
}
}
static void updater_start_app() {
FuriHalRtcBootMode mode = furi_hal_rtc_get_boot_mode();
if((mode != FuriHalRtcBootModePreUpdate) && (mode != FuriHalRtcBootModePostUpdate)) {
return;
@@ -110,11 +98,9 @@ static void updater_start_app() {
* inside loader process, at startup.
* So, accessing its record would cause a deadlock
*/
FuriThread* thread =
furi_thread_alloc_ex("UpdateAppSpawner", 768, updater_spawner_thread_worker, NULL);
furi_thread_set_state_callback(thread, updater_spawner_thread_cleanup);
furi_thread_set_state_context(thread, thread);
furi_thread_start(thread);
Loader* loader = furi_record_open(RECORD_LOADER);
loader_start(loader, "UpdaterApp", NULL);
furi_record_close(RECORD_LOADER);
}
void updater_on_system_start() {
@@ -126,7 +112,7 @@ void updater_on_system_start() {
UNUSED(updater_cli_ep);
#endif
#ifndef FURI_RAM_EXEC
updater_start_app();
furi_timer_pending_callback(updater_start_app, NULL, 0);
#else
UNUSED(updater_start_app);
#endif
@@ -346,7 +346,11 @@ int32_t update_task_worker_flash_writer(void* context) {
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate);
// Format LFS before restoring backup on next boot
furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset);
#ifdef FURI_NDEBUG
// Production
furi_hal_rtc_set_log_level(FuriLogLevelDefault);
furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug);
#endif
update_task_set_progress(update_task, UpdateTaskStageCompleted, 100);
success = true;
} while(false);