mirror of
https://github.com/flipperdevices/flipperzero-firmware.git
synced 2025-12-12 12:51:22 +04:00
Prevent idle priority threads from potentially starving the FreeRTOS idle task (#3909)
* FuriThread: Make FuriThreadPriorityIdle equal to the FreeRTOS one, remove FuriThreadPriorityNone This magic constant was meaningless, FuriThreadPriorityNormal is now assigned by default instead. * Make furi_thread_list_process private Its 'runtime' parameter is to be obtained from FreeRTOS, which means apps cannot do it. * DirectDraw: Remove an useless include and fix memory leak Makes this debug app compileable with uFBT out of the box Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <gui/canvas_i.h>
|
|
||||||
#include <input/input.h>
|
#include <input/input.h>
|
||||||
|
|
||||||
#define BUFFER_SIZE (32U)
|
#define BUFFER_SIZE (32U)
|
||||||
@@ -42,10 +41,11 @@ static DirectDraw* direct_draw_alloc(void) {
|
|||||||
static void direct_draw_free(DirectDraw* instance) {
|
static void direct_draw_free(DirectDraw* instance) {
|
||||||
furi_pubsub_unsubscribe(instance->input, instance->input_subscription);
|
furi_pubsub_unsubscribe(instance->input, instance->input_subscription);
|
||||||
|
|
||||||
instance->canvas = NULL;
|
|
||||||
gui_direct_draw_release(instance->gui);
|
gui_direct_draw_release(instance->gui);
|
||||||
furi_record_close(RECORD_GUI);
|
furi_record_close(RECORD_GUI);
|
||||||
furi_record_close(RECORD_INPUT_EVENTS);
|
furi_record_close(RECORD_INPUT_EVENTS);
|
||||||
|
|
||||||
|
free(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void direct_draw_block(Canvas* canvas, uint32_t size, uint32_t counter) {
|
static void direct_draw_block(Canvas* canvas, uint32_t size, uint32_t counter) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "thread_list.h"
|
#include "thread_list_i.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "memmgr.h"
|
#include "memmgr.h"
|
||||||
#include "memmgr_heap.h"
|
#include "memmgr_heap.h"
|
||||||
@@ -65,6 +65,9 @@ struct FuriThread {
|
|||||||
// IMPORTANT: container MUST be the FIRST struct member
|
// IMPORTANT: container MUST be the FIRST struct member
|
||||||
static_assert(offsetof(FuriThread, container) == 0);
|
static_assert(offsetof(FuriThread, container) == 0);
|
||||||
|
|
||||||
|
// Our idle priority should be equal to the one from FreeRTOS
|
||||||
|
static_assert(FuriThreadPriorityIdle == tskIDLE_PRIORITY);
|
||||||
|
|
||||||
static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size);
|
static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size);
|
||||||
static int32_t __furi_thread_stdout_flush(FuriThread* thread);
|
static int32_t __furi_thread_stdout_flush(FuriThread* thread);
|
||||||
|
|
||||||
@@ -145,6 +148,8 @@ static void furi_thread_init_common(FuriThread* thread) {
|
|||||||
furi_thread_set_appid(thread, "driver");
|
furi_thread_set_appid(thread, "driver");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread->priority = FuriThreadPriorityNormal;
|
||||||
|
|
||||||
FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode();
|
FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode();
|
||||||
if(mode == FuriHalRtcHeapTrackModeAll) {
|
if(mode == FuriHalRtcHeapTrackModeAll) {
|
||||||
thread->heap_trace_enabled = true;
|
thread->heap_trace_enabled = true;
|
||||||
@@ -269,7 +274,7 @@ void furi_thread_set_context(FuriThread* thread, void* context) {
|
|||||||
void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority) {
|
void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority) {
|
||||||
furi_check(thread);
|
furi_check(thread);
|
||||||
furi_check(thread->state == FuriThreadStateStopped);
|
furi_check(thread->state == FuriThreadStateStopped);
|
||||||
furi_check(priority >= FuriThreadPriorityIdle && priority <= FuriThreadPriorityIsr);
|
furi_check(priority <= FuriThreadPriorityIsr);
|
||||||
thread->priority = priority;
|
thread->priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,9 +286,7 @@ FuriThreadPriority furi_thread_get_priority(FuriThread* thread) {
|
|||||||
|
|
||||||
void furi_thread_set_current_priority(FuriThreadPriority priority) {
|
void furi_thread_set_current_priority(FuriThreadPriority priority) {
|
||||||
furi_check(priority <= FuriThreadPriorityIsr);
|
furi_check(priority <= FuriThreadPriorityIsr);
|
||||||
|
vTaskPrioritySet(NULL, priority);
|
||||||
UBaseType_t new_priority = priority ? priority : FuriThreadPriorityNormal;
|
|
||||||
vTaskPrioritySet(NULL, new_priority);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FuriThreadPriority furi_thread_get_current_priority(void) {
|
FuriThreadPriority furi_thread_get_current_priority(void) {
|
||||||
@@ -345,7 +348,6 @@ void furi_thread_start(FuriThread* thread) {
|
|||||||
furi_thread_set_state(thread, FuriThreadStateStarting);
|
furi_thread_set_state(thread, FuriThreadStateStarting);
|
||||||
|
|
||||||
uint32_t stack_depth = thread->stack_size / sizeof(StackType_t);
|
uint32_t stack_depth = thread->stack_size / sizeof(StackType_t);
|
||||||
UBaseType_t priority = thread->priority ? thread->priority : FuriThreadPriorityNormal;
|
|
||||||
|
|
||||||
thread->is_active = true;
|
thread->is_active = true;
|
||||||
|
|
||||||
@@ -355,7 +357,7 @@ void furi_thread_start(FuriThread* thread) {
|
|||||||
thread->name,
|
thread->name,
|
||||||
stack_depth,
|
stack_depth,
|
||||||
thread,
|
thread,
|
||||||
priority,
|
thread->priority,
|
||||||
thread->stack_buffer,
|
thread->stack_buffer,
|
||||||
&thread->container) == (TaskHandle_t)thread);
|
&thread->container) == (TaskHandle_t)thread);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,11 +30,10 @@ typedef enum {
|
|||||||
* @brief Enumeration of possible FuriThread priorities.
|
* @brief Enumeration of possible FuriThread priorities.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FuriThreadPriorityNone = 0, /**< Uninitialized, choose system default */
|
FuriThreadPriorityIdle = 0, /**< Idle priority */
|
||||||
FuriThreadPriorityIdle = 1, /**< Idle priority */
|
|
||||||
FuriThreadPriorityLowest = 14, /**< Lowest */
|
FuriThreadPriorityLowest = 14, /**< Lowest */
|
||||||
FuriThreadPriorityLow = 15, /**< Low */
|
FuriThreadPriorityLow = 15, /**< Low */
|
||||||
FuriThreadPriorityNormal = 16, /**< Normal */
|
FuriThreadPriorityNormal = 16, /**< Normal, system default */
|
||||||
FuriThreadPriorityHigh = 17, /**< High */
|
FuriThreadPriorityHigh = 17, /**< High */
|
||||||
FuriThreadPriorityHighest = 18, /**< Highest */
|
FuriThreadPriorityHighest = 18, /**< Highest */
|
||||||
FuriThreadPriorityIsr =
|
FuriThreadPriorityIsr =
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ FuriThreadListItem* furi_thread_list_get_or_insert(FuriThreadList* instance, Fur
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_thread_list_process(FuriThreadList* instance, uint32_t runtime, uint32_t tick) {
|
void furi_thread_list_process(FuriThreadList* instance, uint32_t runtime, uint32_t tick) {
|
||||||
furi_check(instance);
|
furi_assert(instance);
|
||||||
|
|
||||||
instance->runtime_previous = instance->runtime_current;
|
instance->runtime_previous = instance->runtime_current;
|
||||||
instance->runtime_current = runtime;
|
instance->runtime_current = runtime;
|
||||||
|
|||||||
@@ -68,14 +68,6 @@ FuriThreadListItem* furi_thread_list_get_at(FuriThreadList* instance, size_t pos
|
|||||||
*/
|
*/
|
||||||
FuriThreadListItem* furi_thread_list_get_or_insert(FuriThreadList* instance, FuriThread* thread);
|
FuriThreadListItem* furi_thread_list_get_or_insert(FuriThreadList* instance, FuriThread* thread);
|
||||||
|
|
||||||
/** Process items in the FuriThreadList instance
|
|
||||||
*
|
|
||||||
* @param instance The instance
|
|
||||||
* @param[in] runtime The runtime of the system since start
|
|
||||||
* @param[in] tick The tick when processing happened
|
|
||||||
*/
|
|
||||||
void furi_thread_list_process(FuriThreadList* instance, uint32_t runtime, uint32_t tick);
|
|
||||||
|
|
||||||
/** Get percent of time spent in ISR
|
/** Get percent of time spent in ISR
|
||||||
*
|
*
|
||||||
* @param instance The instance
|
* @param instance The instance
|
||||||
|
|||||||
19
furi/core/thread_list_i.h
Normal file
19
furi/core/thread_list_i.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "thread_list.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Process items in the FuriThreadList instance
|
||||||
|
*
|
||||||
|
* @param instance The instance
|
||||||
|
* @param[in] runtime The runtime of the system since start
|
||||||
|
* @param[in] tick The tick when processing happened
|
||||||
|
*/
|
||||||
|
void furi_thread_list_process(FuriThreadList* instance, uint32_t runtime, uint32_t tick);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,74.0,,
|
Version,+,75.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
@@ -1652,7 +1652,6 @@ Function,+,furi_thread_list_free,void,FuriThreadList*
|
|||||||
Function,+,furi_thread_list_get_at,FuriThreadListItem*,"FuriThreadList*, size_t"
|
Function,+,furi_thread_list_get_at,FuriThreadListItem*,"FuriThreadList*, size_t"
|
||||||
Function,+,furi_thread_list_get_isr_time,float,FuriThreadList*
|
Function,+,furi_thread_list_get_isr_time,float,FuriThreadList*
|
||||||
Function,+,furi_thread_list_get_or_insert,FuriThreadListItem*,"FuriThreadList*, FuriThread*"
|
Function,+,furi_thread_list_get_or_insert,FuriThreadListItem*,"FuriThreadList*, FuriThread*"
|
||||||
Function,+,furi_thread_list_process,void,"FuriThreadList*, uint32_t, uint32_t"
|
|
||||||
Function,+,furi_thread_list_size,size_t,FuriThreadList*
|
Function,+,furi_thread_list_size,size_t,FuriThreadList*
|
||||||
Function,+,furi_thread_resume,void,FuriThreadId
|
Function,+,furi_thread_resume,void,FuriThreadId
|
||||||
Function,+,furi_thread_set_appid,void,"FuriThread*, const char*"
|
Function,+,furi_thread_set_appid,void,"FuriThread*, const char*"
|
||||||
|
|||||||
|
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,74.0,,
|
Version,+,75.0,,
|
||||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||||
@@ -1866,7 +1866,6 @@ Function,+,furi_thread_list_free,void,FuriThreadList*
|
|||||||
Function,+,furi_thread_list_get_at,FuriThreadListItem*,"FuriThreadList*, size_t"
|
Function,+,furi_thread_list_get_at,FuriThreadListItem*,"FuriThreadList*, size_t"
|
||||||
Function,+,furi_thread_list_get_isr_time,float,FuriThreadList*
|
Function,+,furi_thread_list_get_isr_time,float,FuriThreadList*
|
||||||
Function,+,furi_thread_list_get_or_insert,FuriThreadListItem*,"FuriThreadList*, FuriThread*"
|
Function,+,furi_thread_list_get_or_insert,FuriThreadListItem*,"FuriThreadList*, FuriThread*"
|
||||||
Function,+,furi_thread_list_process,void,"FuriThreadList*, uint32_t, uint32_t"
|
|
||||||
Function,+,furi_thread_list_size,size_t,FuriThreadList*
|
Function,+,furi_thread_list_size,size_t,FuriThreadList*
|
||||||
Function,+,furi_thread_resume,void,FuriThreadId
|
Function,+,furi_thread_resume,void,FuriThreadId
|
||||||
Function,+,furi_thread_set_appid,void,"FuriThread*, const char*"
|
Function,+,furi_thread_set_appid,void,"FuriThread*, const char*"
|
||||||
|
|||||||
|
Reference in New Issue
Block a user