Przeglądaj źródła

Core: thread allocation shortcut (#2007)

* Core: thread alloc+set shortcut
* Apps: use thread allocation shortcut
* Mark some service threads as services
* Init BT as soon as possible

Co-authored-by: あく <alleteam@gmail.com>
Sergey Gavrilov 3 lat temu
rodzic
commit
c511c67e71
38 zmienionych plików z 94 dodań i 195 usunięć
  1. 1 5
      applications/debug/uart_echo/uart_echo.c
  2. 4 10
      applications/debug/unit_tests/storage/storage_test.c
  3. 1 6
      applications/main/bad_usb/bad_usb_script.c
  4. 3 10
      applications/main/gpio/usb_uart_bridge.c
  5. 2 5
      applications/main/subghz/helpers/subghz_chat.c
  6. 2 6
      applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c
  7. 1 5
      applications/main/u2f/u2f_hid.c
  8. 0 13
      applications/plugins/dap_link/dap_link.c
  9. 2 5
      applications/plugins/music_player/music_player_worker.c
  10. 2 5
      applications/plugins/nfc_magic/nfc_magic_worker.c
  11. 2 5
      applications/plugins/picopass/picopass_worker.c
  12. 1 4
      applications/services/cli/cli_vcp.c
  13. 1 5
      applications/services/gui/modules/file_browser_worker.c
  14. 1 5
      applications/services/rpc/rpc.c
  15. 2 6
      applications/services/rpc/rpc_gui.c
  16. 2 5
      applications/system/updater/cli/updater_cli.c
  17. 2 5
      applications/system/updater/util/update_task.c
  18. 1 4
      firmware/targets/f7/Src/main.c
  19. 1 0
      firmware/targets/f7/api_symbols.csv
  20. 1 5
      firmware/targets/f7/ble_glue/ble_app.c
  21. 1 5
      firmware/targets/f7/ble_glue/ble_glue.c
  22. 1 5
      firmware/targets/f7/ble_glue/gap.c
  23. 8 9
      firmware/targets/f7/furi_hal/furi_hal.c
  24. 2 4
      firmware/targets/f7/furi_hal/furi_hal_usb.c
  25. 13 0
      furi/core/thread.c
  26. 14 0
      furi/core/thread.h
  27. 5 5
      furi/flipper.c
  28. 3 5
      lib/ST25RFAL002/platform.c
  29. 2 5
      lib/flipper_application/flipper_application.c
  30. 1 4
      lib/infrared/worker/infrared_worker.c
  31. 1 4
      lib/lfrfid/lfrfid_raw_worker.c
  32. 1 5
      lib/lfrfid/lfrfid_worker.c
  33. 2 5
      lib/nfc/helpers/reader_analyzer.c
  34. 1 5
      lib/nfc/nfc_worker.c
  35. 1 5
      lib/one_wire/ibutton/ibutton_worker.c
  36. 2 5
      lib/subghz/subghz_file_encoder_worker.c
  37. 2 5
      lib/subghz/subghz_tx_rx_worker.c
  38. 2 5
      lib/subghz/subghz_worker.c

+ 1 - 5
applications/debug/uart_echo/uart_echo.c

@@ -220,11 +220,7 @@ static UartEchoApp* uart_echo_app_alloc() {
     furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200);
     furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, uart_echo_on_irq_cb, app);
 
-    app->worker_thread = furi_thread_alloc();
-    furi_thread_set_name(app->worker_thread, "UsbUartWorker");
-    furi_thread_set_stack_size(app->worker_thread, 1024);
-    furi_thread_set_context(app->worker_thread, app);
-    furi_thread_set_callback(app->worker_thread, uart_echo_worker);
+    app->worker_thread = furi_thread_alloc_ex("UsbUartWorker", 1024, uart_echo_worker, app);
     furi_thread_start(app->worker_thread);
 
     return app;

+ 4 - 10
applications/debug/unit_tests/storage/storage_test.c

@@ -43,11 +43,8 @@ MU_TEST(storage_file_open_lock) {
     File* file = storage_file_alloc(storage);
 
     // file_locker thread start
-    FuriThread* locker_thread = furi_thread_alloc();
-    furi_thread_set_name(locker_thread, "StorageFileLocker");
-    furi_thread_set_stack_size(locker_thread, 2048);
-    furi_thread_set_context(locker_thread, semaphore);
-    furi_thread_set_callback(locker_thread, storage_file_locker);
+    FuriThread* locker_thread =
+        furi_thread_alloc_ex("StorageFileLocker", 2048, storage_file_locker, semaphore);
     furi_thread_start(locker_thread);
 
     // wait for file lock
@@ -133,11 +130,8 @@ MU_TEST(storage_dir_open_lock) {
     File* file = storage_file_alloc(storage);
 
     // file_locker thread start
-    FuriThread* locker_thread = furi_thread_alloc();
-    furi_thread_set_name(locker_thread, "StorageDirLocker");
-    furi_thread_set_stack_size(locker_thread, 2048);
-    furi_thread_set_context(locker_thread, semaphore);
-    furi_thread_set_callback(locker_thread, storage_dir_locker);
+    FuriThread* locker_thread =
+        furi_thread_alloc_ex("StorageDirLocker", 2048, storage_dir_locker, semaphore);
     furi_thread_start(locker_thread);
 
     // wait for dir lock

+ 1 - 6
applications/main/bad_usb/bad_usb_script.c

@@ -657,12 +657,7 @@ BadUsbScript* bad_usb_script_open(FuriString* file_path) {
     bad_usb->st.state = BadUsbStateInit;
     bad_usb->st.error[0] = '\0';
 
-    bad_usb->thread = furi_thread_alloc();
-    furi_thread_set_name(bad_usb->thread, "BadUsbWorker");
-    furi_thread_set_stack_size(bad_usb->thread, 2048);
-    furi_thread_set_context(bad_usb->thread, bad_usb);
-    furi_thread_set_callback(bad_usb->thread, bad_usb_worker);
-
+    bad_usb->thread = furi_thread_alloc_ex("BadUsbWorker", 2048, bad_usb_worker, bad_usb);
     furi_thread_start(bad_usb->thread);
     return bad_usb;
 }

+ 3 - 10
applications/main/gpio/usb_uart_bridge.c

@@ -159,11 +159,8 @@ static int32_t usb_uart_worker(void* context) {
     usb_uart->tx_sem = furi_semaphore_alloc(1, 1);
     usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
 
-    usb_uart->tx_thread = furi_thread_alloc();
-    furi_thread_set_name(usb_uart->tx_thread, "UsbUartTxWorker");
-    furi_thread_set_stack_size(usb_uart->tx_thread, 512);
-    furi_thread_set_context(usb_uart->tx_thread, usb_uart);
-    furi_thread_set_callback(usb_uart->tx_thread, usb_uart_tx_thread);
+    usb_uart->tx_thread =
+        furi_thread_alloc_ex("UsbUartTxWorker", 512, usb_uart_tx_thread, usb_uart);
 
     usb_uart_vcp_init(usb_uart, usb_uart->cfg.vcp_ch);
     usb_uart_serial_init(usb_uart, usb_uart->cfg.uart_ch);
@@ -338,11 +335,7 @@ UsbUartBridge* usb_uart_enable(UsbUartConfig* cfg) {
 
     memcpy(&(usb_uart->cfg_new), cfg, sizeof(UsbUartConfig));
 
-    usb_uart->thread = furi_thread_alloc();
-    furi_thread_set_name(usb_uart->thread, "UsbUartWorker");
-    furi_thread_set_stack_size(usb_uart->thread, 1024);
-    furi_thread_set_context(usb_uart->thread, usb_uart);
-    furi_thread_set_callback(usb_uart->thread, usb_uart_worker);
+    usb_uart->thread = furi_thread_alloc_ex("UsbUartWorker", 1024, usb_uart_worker, usb_uart);
 
     furi_thread_start(usb_uart->thread);
     return usb_uart;

+ 2 - 5
applications/main/subghz/helpers/subghz_chat.c

@@ -59,11 +59,8 @@ SubGhzChatWorker* subghz_chat_worker_alloc(Cli* cli) {
 
     instance->cli = cli;
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "SubGhzChat");
-    furi_thread_set_stack_size(instance->thread, 2048);
-    furi_thread_set_context(instance->thread, instance);
-    furi_thread_set_callback(instance->thread, subghz_chat_worker_thread);
+    instance->thread =
+        furi_thread_alloc_ex("SubGhzChat", 2048, subghz_chat_worker_thread, instance);
     instance->subghz_txrx = subghz_tx_rx_worker_alloc();
     instance->event_queue = furi_message_queue_alloc(80, sizeof(SubGhzChatEvent));
     return instance;

+ 2 - 6
applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c

@@ -265,12 +265,8 @@ SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc(void* cont
     furi_assert(context);
     SubGhzFrequencyAnalyzerWorker* instance = malloc(sizeof(SubGhzFrequencyAnalyzerWorker));
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "SubGhzFAWorker");
-    furi_thread_set_stack_size(instance->thread, 2048);
-    furi_thread_set_context(instance->thread, instance);
-    furi_thread_set_callback(instance->thread, subghz_frequency_analyzer_worker_thread);
-
+    instance->thread = furi_thread_alloc_ex(
+        "SubGhzFAWorker", 2048, subghz_frequency_analyzer_worker_thread, instance);
     SubGhz* subghz = context;
     instance->setting = subghz->setting;
     return instance;

+ 1 - 5
applications/main/u2f/u2f_hid.c

@@ -282,11 +282,7 @@ U2fHid* u2f_hid_start(U2fData* u2f_inst) {
 
     u2f_hid->u2f_instance = u2f_inst;
 
-    u2f_hid->thread = furi_thread_alloc();
-    furi_thread_set_name(u2f_hid->thread, "U2fHidWorker");
-    furi_thread_set_stack_size(u2f_hid->thread, 2048);
-    furi_thread_set_context(u2f_hid->thread, u2f_hid);
-    furi_thread_set_callback(u2f_hid->thread, u2f_hid_worker);
+    u2f_hid->thread = furi_thread_alloc_ex("U2fHidWorker", 2048, u2f_hid_worker, u2f_hid);
     furi_thread_start(u2f_hid->thread);
     return u2f_hid;
 }

+ 0 - 13
applications/plugins/dap_link/dap_link.c

@@ -441,19 +441,6 @@ static int32_t cdc_process(void* p) {
 /******************************* MAIN APP **********************************/
 /***************************************************************************/
 
-static FuriThread* furi_thread_alloc_ex(
-    const char* name,
-    uint32_t stack_size,
-    FuriThreadCallback callback,
-    void* context) {
-    FuriThread* thread = furi_thread_alloc();
-    furi_thread_set_name(thread, name);
-    furi_thread_set_stack_size(thread, stack_size);
-    furi_thread_set_callback(thread, callback);
-    furi_thread_set_context(thread, context);
-    return thread;
-}
-
 static DapApp* dap_app_alloc() {
     DapApp* dap_app = malloc(sizeof(DapApp));
     dap_app->dap_thread = furi_thread_alloc_ex("DAP Process", 1024, dap_process, dap_app);

+ 2 - 5
applications/plugins/music_player/music_player_worker.c

@@ -97,11 +97,8 @@ MusicPlayerWorker* music_player_worker_alloc() {
 
     NoteBlockArray_init(instance->notes);
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "MusicPlayerWorker");
-    furi_thread_set_stack_size(instance->thread, 1024);
-    furi_thread_set_context(instance->thread, instance);
-    furi_thread_set_callback(instance->thread, music_player_worker_thread_callback);
+    instance->thread = furi_thread_alloc_ex(
+        "MusicPlayerWorker", 1024, music_player_worker_thread_callback, instance);
 
     instance->volume = 1.0f;
 

+ 2 - 5
applications/plugins/nfc_magic/nfc_magic_worker.c

@@ -15,11 +15,8 @@ NfcMagicWorker* nfc_magic_worker_alloc() {
     NfcMagicWorker* nfc_magic_worker = malloc(sizeof(NfcMagicWorker));
 
     // Worker thread attributes
-    nfc_magic_worker->thread = furi_thread_alloc();
-    furi_thread_set_name(nfc_magic_worker->thread, "NfcMagicWorker");
-    furi_thread_set_stack_size(nfc_magic_worker->thread, 8192);
-    furi_thread_set_callback(nfc_magic_worker->thread, nfc_magic_worker_task);
-    furi_thread_set_context(nfc_magic_worker->thread, nfc_magic_worker);
+    nfc_magic_worker->thread =
+        furi_thread_alloc_ex("NfcMagicWorker", 8192, nfc_magic_worker_task, nfc_magic_worker);
 
     nfc_magic_worker->callback = NULL;
     nfc_magic_worker->context = NULL;

+ 2 - 5
applications/plugins/picopass/picopass_worker.c

@@ -25,11 +25,8 @@ PicopassWorker* picopass_worker_alloc() {
     PicopassWorker* picopass_worker = malloc(sizeof(PicopassWorker));
 
     // Worker thread attributes
-    picopass_worker->thread = furi_thread_alloc();
-    furi_thread_set_name(picopass_worker->thread, "PicopassWorker");
-    furi_thread_set_stack_size(picopass_worker->thread, 8192);
-    furi_thread_set_callback(picopass_worker->thread, picopass_worker_task);
-    furi_thread_set_context(picopass_worker->thread, picopass_worker);
+    picopass_worker->thread =
+        furi_thread_alloc_ex("PicopassWorker", 8192, picopass_worker_task, picopass_worker);
 
     picopass_worker->callback = NULL;
     picopass_worker->context = NULL;

+ 1 - 4
applications/services/cli/cli_vcp.c

@@ -68,10 +68,7 @@ static void cli_vcp_init() {
 
     vcp->connected = false;
 
-    vcp->thread = furi_thread_alloc();
-    furi_thread_set_name(vcp->thread, "CliVcpWorker");
-    furi_thread_set_stack_size(vcp->thread, 1024);
-    furi_thread_set_callback(vcp->thread, vcp_worker);
+    vcp->thread = furi_thread_alloc_ex("CliVcpWorker", 1024, vcp_worker, NULL);
     furi_thread_start(vcp->thread);
 
     FURI_LOG_I(TAG, "Init OK");

+ 1 - 5
applications/services/gui/modules/file_browser_worker.c

@@ -367,11 +367,7 @@ BrowserWorker*
     browser->skip_assets = skip_assets;
     browser->path_next = furi_string_alloc_set(path);
 
-    browser->thread = furi_thread_alloc();
-    furi_thread_set_name(browser->thread, "BrowserWorker");
-    furi_thread_set_stack_size(browser->thread, 2048);
-    furi_thread_set_context(browser->thread, browser);
-    furi_thread_set_callback(browser->thread, browser_worker);
+    browser->thread = furi_thread_alloc_ex("BrowserWorker", 2048, browser_worker, browser);
     furi_thread_start(browser->thread);
 
     return browser;

+ 1 - 5
applications/services/rpc/rpc.c

@@ -370,11 +370,7 @@ RpcSession* rpc_session_open(Rpc* rpc) {
     };
     rpc_add_handler(session, PB_Main_stop_session_tag, &rpc_handler);
 
-    session->thread = furi_thread_alloc();
-    furi_thread_set_name(session->thread, "RpcSessionWorker");
-    furi_thread_set_stack_size(session->thread, 3072);
-    furi_thread_set_context(session->thread, session);
-    furi_thread_set_callback(session->thread, rpc_session_worker);
+    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);

+ 2 - 6
applications/services/rpc/rpc_gui.c

@@ -88,12 +88,8 @@ static void rpc_system_gui_start_screen_stream_process(const PB_Main* request, v
             malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(framebuffer_size));
         rpc_gui->transmit_frame->content.gui_screen_frame.data->size = framebuffer_size;
         // Transmission thread for async TX
-        rpc_gui->transmit_thread = furi_thread_alloc();
-        furi_thread_set_name(rpc_gui->transmit_thread, "GuiRpcWorker");
-        furi_thread_set_callback(
-            rpc_gui->transmit_thread, rpc_system_gui_screen_stream_frame_transmit_thread);
-        furi_thread_set_context(rpc_gui->transmit_thread, rpc_gui);
-        furi_thread_set_stack_size(rpc_gui->transmit_thread, 1024);
+        rpc_gui->transmit_thread = furi_thread_alloc_ex(
+            "GuiRpcWorker", 1024, rpc_system_gui_screen_stream_frame_transmit_thread, rpc_gui);
         furi_thread_start(rpc_gui->transmit_thread);
         // GUI framebuffer callback
         gui_add_framebuffer_callback(

+ 2 - 5
applications/system/updater/cli/updater_cli.c

@@ -110,11 +110,8 @@ static void updater_start_app() {
      * inside loader process, at startup. 
      * So, accessing its record would cause a deadlock 
      */
-    FuriThread* thread = furi_thread_alloc();
-
-    furi_thread_set_name(thread, "UpdateAppSpawner");
-    furi_thread_set_stack_size(thread, 768);
-    furi_thread_set_callback(thread, updater_spawner_thread_worker);
+    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);

+ 2 - 5
applications/system/updater/util/update_task.c

@@ -216,11 +216,8 @@ UpdateTask* update_task_alloc() {
     update_task->boot_mode = furi_hal_rtc_get_boot_mode();
     update_task->update_path = furi_string_alloc();
 
-    FuriThread* thread = update_task->thread = furi_thread_alloc();
-
-    furi_thread_set_name(thread, "UpdateWorker");
-    furi_thread_set_stack_size(thread, 5120);
-    furi_thread_set_context(thread, update_task);
+    FuriThread* thread = update_task->thread =
+        furi_thread_alloc_ex("UpdateWorker", 5120, NULL, update_task);
 
     furi_thread_set_state_callback(thread, update_task_worker_thread_cb);
     furi_thread_set_state_context(thread, update_task);

+ 1 - 4
firmware/targets/f7/Src/main.c

@@ -26,10 +26,7 @@ int main() {
     // Flipper critical FURI HAL
     furi_hal_init_early();
 
-    FuriThread* main_thread = furi_thread_alloc();
-    furi_thread_set_name(main_thread, "Init");
-    furi_thread_set_stack_size(main_thread, 4096);
-    furi_thread_set_callback(main_thread, init_task);
+    FuriThread* main_thread = furi_thread_alloc_ex("Init", 4096, init_task, NULL);
 
 #ifdef FURI_RAM_EXEC
     furi_thread_start(main_thread);

+ 1 - 0
firmware/targets/f7/api_symbols.csv

@@ -1471,6 +1471,7 @@ Function,+,furi_string_utf8_length,size_t,FuriString*
 Function,+,furi_string_utf8_push,void,"FuriString*, FuriStringUnicodeValue"
 Function,+,furi_string_vprintf,int,"FuriString*, const char[], va_list"
 Function,+,furi_thread_alloc,FuriThread*,
+Function,+,furi_thread_alloc_ex,FuriThread*,"const char*, uint32_t, FuriThreadCallback, void*"
 Function,+,furi_thread_catch,void,
 Function,-,furi_thread_disable_heap_trace,void,FuriThread*
 Function,+,furi_thread_enable_heap_trace,void,FuriThread*

+ 1 - 5
firmware/targets/f7/ble_glue/ble_app.c

@@ -40,11 +40,7 @@ bool ble_app_init() {
     ble_app->hci_mtx = furi_mutex_alloc(FuriMutexTypeNormal);
     ble_app->hci_sem = furi_semaphore_alloc(1, 0);
     // HCI transport layer thread to handle user asynch events
-    ble_app->thread = furi_thread_alloc();
-    furi_thread_set_name(ble_app->thread, "BleHciDriver");
-    furi_thread_set_stack_size(ble_app->thread, 1024);
-    furi_thread_set_context(ble_app->thread, ble_app);
-    furi_thread_set_callback(ble_app->thread, ble_app_hci_thread);
+    ble_app->thread = furi_thread_alloc_ex("BleHciDriver", 1024, ble_app_hci_thread, ble_app);
     furi_thread_start(ble_app->thread);
 
     // Initialize Ble Transport Layer

+ 1 - 5
firmware/targets/f7/ble_glue/ble_glue.c

@@ -78,11 +78,7 @@ void ble_glue_init() {
     ble_glue->shci_sem = furi_semaphore_alloc(1, 0);
 
     // FreeRTOS system task creation
-    ble_glue->thread = furi_thread_alloc();
-    furi_thread_set_name(ble_glue->thread, "BleShciDriver");
-    furi_thread_set_stack_size(ble_glue->thread, 1024);
-    furi_thread_set_context(ble_glue->thread, ble_glue);
-    furi_thread_set_callback(ble_glue->thread, ble_glue_shci_thread);
+    ble_glue->thread = furi_thread_alloc_ex("BleShciDriver", 1024, ble_glue_shci_thread, ble_glue);
     furi_thread_start(ble_glue->thread);
 
     // System channel initialization

+ 1 - 5
firmware/targets/f7/ble_glue/gap.c

@@ -492,11 +492,7 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) {
     gap->enable_adv = true;
 
     // Thread configuration
-    gap->thread = furi_thread_alloc();
-    furi_thread_set_name(gap->thread, "BleGapDriver");
-    furi_thread_set_stack_size(gap->thread, 1024);
-    furi_thread_set_context(gap->thread, gap);
-    furi_thread_set_callback(gap->thread, gap_app);
+    gap->thread = furi_thread_alloc_ex("BleGapDriver", 1024, gap_app, gap);
     furi_thread_start(gap->thread);
 
     // Command queue allocation

+ 8 - 9
firmware/targets/f7/furi_hal/furi_hal.c

@@ -61,26 +61,25 @@ void furi_hal_init() {
 
     furi_hal_crypto_init();
 
-    // USB
-#ifndef FURI_RAM_EXEC
-    furi_hal_usb_init();
-    FURI_LOG_I(TAG, "USB OK");
-#endif
-
     furi_hal_i2c_init();
 
     // High Level
     furi_hal_power_init();
     furi_hal_light_init();
+
+    furi_hal_bt_init();
+    furi_hal_memory_init();
+    furi_hal_compress_icon_init();
+
 #ifndef FURI_RAM_EXEC
+    // USB
+    furi_hal_usb_init();
+    FURI_LOG_I(TAG, "USB OK");
     furi_hal_vibro_init();
     furi_hal_subghz_init();
     furi_hal_nfc_init();
     furi_hal_rfid_init();
 #endif
-    furi_hal_bt_init();
-    furi_hal_memory_init();
-    furi_hal_compress_icon_init();
 
     // FatFS driver initialization
     MX_FATFS_Init();

+ 2 - 4
firmware/targets/f7/furi_hal/furi_hal_usb.c

@@ -80,10 +80,8 @@ void furi_hal_usb_init(void) {
     NVIC_EnableIRQ(USB_LP_IRQn);
     NVIC_EnableIRQ(USB_HP_IRQn);
 
-    usb.thread = furi_thread_alloc();
-    furi_thread_set_name(usb.thread, "UsbDriver");
-    furi_thread_set_stack_size(usb.thread, 1024);
-    furi_thread_set_callback(usb.thread, furi_hal_usb_thread);
+    usb.thread = furi_thread_alloc_ex("UsbDriver", 1024, furi_hal_usb_thread, NULL);
+    furi_thread_mark_as_service(usb.thread);
     furi_thread_start(usb.thread);
 
     FURI_LOG_I(TAG, "Init OK");

+ 13 - 0
furi/core/thread.c

@@ -135,6 +135,19 @@ FuriThread* furi_thread_alloc() {
     return thread;
 }
 
+FuriThread* furi_thread_alloc_ex(
+    const char* name,
+    uint32_t stack_size,
+    FuriThreadCallback callback,
+    void* context) {
+    FuriThread* thread = furi_thread_alloc();
+    furi_thread_set_name(thread, name);
+    furi_thread_set_stack_size(thread, stack_size);
+    furi_thread_set_callback(thread, callback);
+    furi_thread_set_context(thread, context);
+    return thread;
+}
+
 void furi_thread_free(FuriThread* thread) {
     furi_assert(thread);
     furi_assert(thread->state == FuriThreadStateStopped);

+ 14 - 0
furi/core/thread.h

@@ -60,6 +60,20 @@ typedef void (*FuriThreadStateCallback)(FuriThreadState state, void* context);
  */
 FuriThread* furi_thread_alloc();
 
+/** Allocate FuriThread, shortcut version
+ * 
+ * @param name 
+ * @param stack_size 
+ * @param callback 
+ * @param context 
+ * @return FuriThread* 
+ */
+FuriThread* furi_thread_alloc_ex(
+    const char* name,
+    uint32_t stack_size,
+    FuriThreadCallback callback,
+    void* context);
+
 /** Release FuriThread
  *
  * @param      thread  FuriThread instance

+ 5 - 5
furi/flipper.c

@@ -34,11 +34,11 @@ void flipper_init() {
     for(size_t i = 0; i < FLIPPER_SERVICES_COUNT; i++) {
         FURI_LOG_I(TAG, "starting service %s", FLIPPER_SERVICES[i].name);
 
-        FuriThread* thread = furi_thread_alloc();
-
-        furi_thread_set_name(thread, FLIPPER_SERVICES[i].name);
-        furi_thread_set_stack_size(thread, FLIPPER_SERVICES[i].stack_size);
-        furi_thread_set_callback(thread, FLIPPER_SERVICES[i].app);
+        FuriThread* thread = furi_thread_alloc_ex(
+            FLIPPER_SERVICES[i].name,
+            FLIPPER_SERVICES[i].stack_size,
+            FLIPPER_SERVICES[i].app,
+            NULL);
         furi_thread_mark_as_service(thread);
 
         furi_thread_start(thread);

+ 3 - 5
lib/ST25RFAL002/platform.c

@@ -45,11 +45,9 @@ void platformDisableIrqCallback() {
 
 void platformSetIrqCallback(PlatformIrqCallback callback) {
     rfal_platform.callback = callback;
-    rfal_platform.thread = furi_thread_alloc();
-
-    furi_thread_set_name(rfal_platform.thread, "RfalIrqDriver");
-    furi_thread_set_callback(rfal_platform.thread, rfal_platform_irq_thread);
-    furi_thread_set_stack_size(rfal_platform.thread, 1024);
+    rfal_platform.thread =
+        furi_thread_alloc_ex("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL);
+    furi_thread_mark_as_service(rfal_platform.thread);
     furi_thread_set_priority(rfal_platform.thread, FuriThreadPriorityIsr);
     furi_thread_start(rfal_platform.thread);
 

+ 2 - 5
lib/flipper_application/flipper_application.c

@@ -104,11 +104,8 @@ FuriThread* flipper_application_spawn(FlipperApplication* app, void* args) {
     const FlipperApplicationManifest* manifest = flipper_application_get_manifest(app);
     furi_check(manifest->stack_size > 0);
 
-    app->thread = furi_thread_alloc();
-    furi_thread_set_stack_size(app->thread, manifest->stack_size);
-    furi_thread_set_name(app->thread, manifest->name);
-    furi_thread_set_callback(app->thread, flipper_application_thread);
-    furi_thread_set_context(app->thread, args);
+    app->thread = furi_thread_alloc_ex(
+        manifest->name, manifest->stack_size, flipper_application_thread, args);
 
     return app->thread;
 }

+ 1 - 4
lib/infrared/worker/infrared_worker.c

@@ -223,10 +223,7 @@ void infrared_worker_rx_set_received_signal_callback(
 InfraredWorker* infrared_worker_alloc() {
     InfraredWorker* instance = malloc(sizeof(InfraredWorker));
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "InfraredWorker");
-    furi_thread_set_stack_size(instance->thread, 2048);
-    furi_thread_set_context(instance->thread, instance);
+    instance->thread = furi_thread_alloc_ex("InfraredWorker", 2048, NULL, instance);
 
     size_t buffer_size =
         MAX(sizeof(InfraredWorkerTiming) * (MAX_TIMINGS_AMOUNT + 1),

+ 1 - 4
lib/lfrfid/lfrfid_raw_worker.c

@@ -61,10 +61,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context);
 LFRFIDRawWorker* lfrfid_raw_worker_alloc() {
     LFRFIDRawWorker* worker = malloc(sizeof(LFRFIDRawWorker));
 
-    worker->thread = furi_thread_alloc();
-    furi_thread_set_name(worker->thread, "lfrfid_raw_worker");
-    furi_thread_set_context(worker->thread, worker);
-    furi_thread_set_stack_size(worker->thread, 2048);
+    worker->thread = furi_thread_alloc_ex("LfrfidRawWorker", 2048, NULL, worker);
 
     worker->events = furi_event_flag_alloc(NULL);
 

+ 1 - 5
lib/lfrfid/lfrfid_worker.c

@@ -29,11 +29,7 @@ LFRFIDWorker* lfrfid_worker_alloc(ProtocolDict* dict) {
     worker->raw_filename = NULL;
     worker->mode_storage = NULL;
 
-    worker->thread = furi_thread_alloc();
-    furi_thread_set_name(worker->thread, "lfrfid_worker");
-    furi_thread_set_callback(worker->thread, lfrfid_worker_thread);
-    furi_thread_set_context(worker->thread, worker);
-    furi_thread_set_stack_size(worker->thread, 2048);
+    worker->thread = furi_thread_alloc_ex("LfrfidWorker", 2048, lfrfid_worker_thread, worker);
 
     worker->protocols = dict;
 

+ 2 - 5
lib/nfc/helpers/reader_analyzer.c

@@ -104,11 +104,8 @@ ReaderAnalyzer* reader_analyzer_alloc() {
     instance->stream =
         furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader));
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "ReaderAnalyzerWorker");
-    furi_thread_set_stack_size(instance->thread, 2048);
-    furi_thread_set_callback(instance->thread, reader_analyzer_thread);
-    furi_thread_set_context(instance->thread, instance);
+    instance->thread =
+        furi_thread_alloc_ex("ReaderAnalyzerWorker", 2048, reader_analyzer_thread, instance);
     furi_thread_set_priority(instance->thread, FuriThreadPriorityLow);
 
     return instance;

+ 1 - 5
lib/nfc/nfc_worker.c

@@ -12,11 +12,7 @@ NfcWorker* nfc_worker_alloc() {
     NfcWorker* nfc_worker = malloc(sizeof(NfcWorker));
 
     // Worker thread attributes
-    nfc_worker->thread = furi_thread_alloc();
-    furi_thread_set_name(nfc_worker->thread, "NfcWorker");
-    furi_thread_set_stack_size(nfc_worker->thread, 8192);
-    furi_thread_set_callback(nfc_worker->thread, nfc_worker_task);
-    furi_thread_set_context(nfc_worker->thread, nfc_worker);
+    nfc_worker->thread = furi_thread_alloc_ex("NfcWorker", 8192, nfc_worker_task, nfc_worker);
 
     nfc_worker->callback = NULL;
     nfc_worker->context = NULL;

+ 1 - 5
lib/one_wire/ibutton/ibutton_worker.c

@@ -37,11 +37,7 @@ iButtonWorker* ibutton_worker_alloc() {
     worker->emulate_cb = NULL;
     worker->cb_ctx = NULL;
 
-    worker->thread = furi_thread_alloc();
-    furi_thread_set_name(worker->thread, "ibutton_worker");
-    furi_thread_set_callback(worker->thread, ibutton_worker_thread);
-    furi_thread_set_context(worker->thread, worker);
-    furi_thread_set_stack_size(worker->thread, 2048);
+    worker->thread = furi_thread_alloc_ex("iButtonWorker", 2048, ibutton_worker_thread, worker);
 
     worker->protocols = protocol_dict_alloc(ibutton_protocols, iButtonProtocolMax);
 

+ 2 - 5
lib/subghz/subghz_file_encoder_worker.c

@@ -174,11 +174,8 @@ static int32_t subghz_file_encoder_worker_thread(void* context) {
 SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() {
     SubGhzFileEncoderWorker* instance = malloc(sizeof(SubGhzFileEncoderWorker));
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "SubGhzFEWorker");
-    furi_thread_set_stack_size(instance->thread, 2048);
-    furi_thread_set_context(instance->thread, instance);
-    furi_thread_set_callback(instance->thread, subghz_file_encoder_worker_thread);
+    instance->thread =
+        furi_thread_alloc_ex("SubGhzFEWorker", 2048, subghz_file_encoder_worker_thread, instance);
     instance->stream = furi_stream_buffer_alloc(sizeof(int32_t) * 2048, sizeof(int32_t));
 
     instance->storage = furi_record_open(RECORD_STORAGE);

+ 2 - 5
lib/subghz/subghz_tx_rx_worker.c

@@ -201,11 +201,8 @@ static int32_t subghz_tx_rx_worker_thread(void* context) {
 SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() {
     SubGhzTxRxWorker* instance = malloc(sizeof(SubGhzTxRxWorker));
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "SubGhzTxRxWorker");
-    furi_thread_set_stack_size(instance->thread, 2048);
-    furi_thread_set_context(instance->thread, instance);
-    furi_thread_set_callback(instance->thread, subghz_tx_rx_worker_thread);
+    instance->thread =
+        furi_thread_alloc_ex("SubGhzTxRxWorker", 2048, subghz_tx_rx_worker_thread, instance);
     instance->stream_tx =
         furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t));
     instance->stream_rx =

+ 2 - 5
lib/subghz/subghz_worker.c

@@ -88,11 +88,8 @@ static int32_t subghz_worker_thread_callback(void* context) {
 SubGhzWorker* subghz_worker_alloc() {
     SubGhzWorker* instance = malloc(sizeof(SubGhzWorker));
 
-    instance->thread = furi_thread_alloc();
-    furi_thread_set_name(instance->thread, "SubGhzWorker");
-    furi_thread_set_stack_size(instance->thread, 2048);
-    furi_thread_set_context(instance->thread, instance);
-    furi_thread_set_callback(instance->thread, subghz_worker_thread_callback);
+    instance->thread =
+        furi_thread_alloc_ex("SubGhzWorker", 2048, subghz_worker_thread_callback, instance);
 
     instance->stream =
         furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration));