[FL-2591] Furi: remove CMSIS thread api, migrate to FuriThread, remove unused CMSIS APIs (#1333)

* Furi: remove CMSIS thread api, migrate to FuriThread, remove unused CMSIS APIs
* Furi: magic thread catcher validating thread completion; backtrace improver
* Furi: allow furi_thread_get_current_id outside of thread context
* Furi: use IRQ instead of ISR for core primitives
This commit is contained in:
あく
2022-06-20 17:54:48 +03:00
committed by GitHub
parent 7618c8ba6f
commit 839e52ac32
61 changed files with 1467 additions and 2784 deletions

View File

@@ -440,9 +440,9 @@ static void bad_usb_hid_state_callback(bool state, void* context) {
BadUsbScript* bad_usb = context;
if(state == true)
osThreadFlagsSet(furi_thread_get_thread_id(bad_usb->thread), WorkerEvtConnect);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtConnect);
else
osThreadFlagsSet(furi_thread_get_thread_id(bad_usb->thread), WorkerEvtDisconnect);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtDisconnect);
}
static int32_t bad_usb_worker(void* context) {
@@ -483,8 +483,8 @@ static int32_t bad_usb_worker(void* context) {
bad_usb->st.state = worker_state;
} else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected
uint32_t flags =
osThreadFlagsWait(WorkerEvtEnd | WorkerEvtConnect, osFlagsWaitAny, osWaitForever);
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtConnect, osFlagsWaitAny, osWaitForever);
furi_check((flags & osFlagsError) == 0);
if(flags & WorkerEvtEnd) {
break;
@@ -494,7 +494,7 @@ static int32_t bad_usb_worker(void* context) {
bad_usb->st.state = worker_state;
} else if(worker_state == BadUsbStateIdle) { // State: ready to start
uint32_t flags = osThreadFlagsWait(
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect,
osFlagsWaitAny,
osWaitForever);
@@ -518,7 +518,7 @@ static int32_t bad_usb_worker(void* context) {
} else if(worker_state == BadUsbStateRunning) { // State: running
uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val);
uint32_t flags = osThreadFlagsWait(
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, osFlagsWaitAny, delay_cur);
delay_val -= delay_cur;
if(!(flags & osFlagsError)) {
@@ -561,7 +561,7 @@ static int32_t bad_usb_worker(void* context) {
} else if(
(worker_state == BadUsbStateFileError) ||
(worker_state == BadUsbStateScriptError)) { // State: error
uint32_t flags = osThreadFlagsWait(
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd, osFlagsWaitAny, osWaitForever); // Waiting for exit command
furi_check((flags & osFlagsError) == 0);
if(flags & WorkerEvtEnd) {
@@ -605,7 +605,7 @@ BadUsbScript* bad_usb_script_open(string_t file_path) {
void bad_usb_script_close(BadUsbScript* bad_usb) {
furi_assert(bad_usb);
osThreadFlagsSet(furi_thread_get_thread_id(bad_usb->thread), WorkerEvtEnd);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtEnd);
furi_thread_join(bad_usb->thread);
furi_thread_free(bad_usb->thread);
string_clear(bad_usb->file_path);
@@ -614,7 +614,7 @@ void bad_usb_script_close(BadUsbScript* bad_usb) {
void bad_usb_script_toggle(BadUsbScript* bad_usb) {
furi_assert(bad_usb);
osThreadFlagsSet(furi_thread_get_thread_id(bad_usb->thread), WorkerEvtToggle);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtToggle);
}
BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb) {

View File

@@ -255,19 +255,19 @@ void cli_command_ps(Cli* cli, string_t args, void* context) {
UNUSED(context);
const uint8_t threads_num_max = 32;
osThreadId_t threads_id[threads_num_max];
uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max);
FuriThreadId threads_ids[threads_num_max];
uint8_t thread_num = furi_thread_enumerate(threads_ids, threads_num_max);
printf(
"%-20s %-14s %-8s %-8s %s\r\n", "Name", "Stack start", "Heap", "Stack", "Stack min free");
for(uint8_t i = 0; i < thread_num; i++) {
TaskControlBlock* tcb = (TaskControlBlock*)threads_id[i];
TaskControlBlock* tcb = (TaskControlBlock*)threads_ids[i];
printf(
"%-20s 0x%-12lx %-8d %-8ld %-8ld\r\n",
osThreadGetName(threads_id[i]),
furi_thread_get_name(threads_ids[i]),
(uint32_t)tcb->pxStack,
memmgr_heap_get_thread_memory(threads_id[i]),
memmgr_heap_get_thread_memory(threads_ids[i]),
(uint32_t)(tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(StackType_t),
osThreadGetStackSpace(threads_id[i]));
furi_thread_get_stack_space(threads_ids[i]));
}
printf("\r\nTotal: %d", thread_num);
}

View File

@@ -79,7 +79,7 @@ static void cli_vcp_init() {
}
static void cli_vcp_deinit() {
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtStop);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStop);
furi_thread_join(vcp->thread);
furi_thread_free(vcp->thread);
vcp->thread = NULL;
@@ -102,7 +102,8 @@ static int32_t vcp_worker(void* context) {
vcp->running = true;
while(1) {
uint32_t flags = osThreadFlagsWait(VCP_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever);
uint32_t flags =
furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever);
furi_assert((flags & osFlagsError) == 0);
// VCP session opened
@@ -232,7 +233,7 @@ static size_t cli_vcp_rx(uint8_t* buffer, size_t size, uint32_t timeout) {
FURI_LOG_D(TAG, "rx %u ", batch_size);
#endif
if(len == 0) break;
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtStreamRx);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamRx);
size -= len;
buffer += len;
rx_cnt += len;
@@ -261,7 +262,7 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) {
if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN;
xStreamBufferSend(vcp->tx_stream, buffer, batch_size, osWaitForever);
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtStreamTx);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx);
#ifdef CLI_VCP_DEBUG
FURI_LOG_D(TAG, "tx %u", batch_size);
#endif
@@ -283,7 +284,7 @@ static void cli_vcp_tx_stdout(void* _cookie, const char* data, size_t size) {
static void vcp_state_callback(void* context, uint8_t state) {
UNUSED(context);
if(state == 0) {
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtDisconnect);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtDisconnect);
}
}
@@ -293,21 +294,21 @@ static void vcp_on_cdc_control_line(void* context, uint8_t state) {
bool dtr = state & (1 << 0);
if(dtr == true) {
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtConnect);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtConnect);
} else {
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtDisconnect);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtDisconnect);
}
}
static void vcp_on_cdc_rx(void* context) {
UNUSED(context);
uint32_t ret = osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtRx);
uint32_t ret = furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtRx);
furi_check((ret & osFlagsError) == 0);
}
static void vcp_on_cdc_tx_complete(void* context) {
UNUSED(context);
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtTx);
furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtTx);
}
static bool cli_vcp_is_connected(void) {

View File

@@ -97,7 +97,7 @@ static void uart_echo_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
if(ev == UartIrqEventRXNE) {
xStreamBufferSendFromISR(app->rx_stream, &data, 1, &xHigherPriorityTaskWoken);
osThreadFlagsSet(furi_thread_get_thread_id(app->worker_thread), WorkerEventRx);
furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventRx);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
@@ -149,7 +149,8 @@ static int32_t uart_echo_worker(void* context) {
UartEchoApp* app = context;
while(1) {
uint32_t events = osThreadFlagsWait(WORKER_EVENTS_MASK, osFlagsWaitAny, osWaitForever);
uint32_t events =
furi_thread_flags_wait(WORKER_EVENTS_MASK, osFlagsWaitAny, osWaitForever);
furi_check((events & osFlagsError) == 0);
if(events & WorkerEventStop) break;
@@ -234,7 +235,7 @@ static UartEchoApp* uart_echo_app_alloc() {
static void uart_echo_app_free(UartEchoApp* app) {
furi_assert(app);
osThreadFlagsSet(furi_thread_get_thread_id(app->worker_thread), WorkerEventStop);
furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventStop);
furi_thread_join(app->worker_thread);
furi_thread_free(app->worker_thread);

View File

@@ -78,7 +78,7 @@ static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
if(ev == UartIrqEventRXNE) {
xStreamBufferSendFromISR(usb_uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken);
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtRxDone);
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
@@ -181,12 +181,13 @@ static int32_t usb_uart_worker(void* context) {
usb_uart_update_ctrl_lines(usb_uart);
}
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->tx_thread), WorkerEvtCdcRx);
furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtCdcRx);
furi_thread_start(usb_uart->tx_thread);
while(1) {
uint32_t events = osThreadFlagsWait(WORKER_ALL_RX_EVENTS, osFlagsWaitAny, osWaitForever);
uint32_t events =
furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, osFlagsWaitAny, osWaitForever);
furi_check((events & osFlagsError) == 0);
if(events & WorkerEvtStop) break;
if(events & WorkerEvtRxDone) {
@@ -205,7 +206,7 @@ static int32_t usb_uart_worker(void* context) {
}
if(events & WorkerEvtCfgChange) {
if(usb_uart->cfg.vcp_ch != usb_uart->cfg_new.vcp_ch) {
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->tx_thread), WorkerEvtTxStop);
furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtTxStop);
furi_thread_join(usb_uart->tx_thread);
usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch);
@@ -217,7 +218,7 @@ static int32_t usb_uart_worker(void* context) {
events |= WorkerEvtLineCfgSet;
}
if(usb_uart->cfg.uart_ch != usb_uart->cfg_new.uart_ch) {
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->tx_thread), WorkerEvtTxStop);
furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtTxStop);
furi_thread_join(usb_uart->tx_thread);
usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch);
@@ -266,7 +267,7 @@ static int32_t usb_uart_worker(void* context) {
furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog);
}
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->tx_thread), WorkerEvtTxStop);
furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtTxStop);
furi_thread_join(usb_uart->tx_thread);
furi_thread_free(usb_uart->tx_thread);
@@ -288,7 +289,8 @@ static int32_t usb_uart_tx_thread(void* context) {
uint8_t data[USB_CDC_PKT_LEN];
while(1) {
uint32_t events = osThreadFlagsWait(WORKER_ALL_TX_EVENTS, osFlagsWaitAny, osWaitForever);
uint32_t events =
furi_thread_flags_wait(WORKER_ALL_TX_EVENTS, osFlagsWaitAny, osWaitForever);
furi_check((events & osFlagsError) == 0);
if(events & WorkerEvtTxStop) break;
if(events & WorkerEvtCdcRx) {
@@ -314,7 +316,7 @@ static void vcp_on_cdc_tx_complete(void* context) {
static void vcp_on_cdc_rx(void* context) {
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->tx_thread), WorkerEvtCdcRx);
furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtCdcRx);
}
static void vcp_state_callback(void* context, uint8_t state) {
@@ -325,13 +327,13 @@ static void vcp_state_callback(void* context, uint8_t state) {
static void vcp_on_cdc_control_line(void* context, uint8_t state) {
UNUSED(state);
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtCtrlLineSet);
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtCtrlLineSet);
}
static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) {
UNUSED(config);
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtLineCfgSet);
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtLineCfgSet);
}
UsbUartBridge* usb_uart_enable(UsbUartConfig* cfg) {
@@ -351,7 +353,7 @@ UsbUartBridge* usb_uart_enable(UsbUartConfig* cfg) {
void usb_uart_disable(UsbUartBridge* usb_uart) {
furi_assert(usb_uart);
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtStop);
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtStop);
furi_thread_join(usb_uart->thread);
furi_thread_free(usb_uart->thread);
free(usb_uart);
@@ -361,7 +363,7 @@ void usb_uart_set_config(UsbUartBridge* usb_uart, UsbUartConfig* cfg) {
furi_assert(usb_uart);
furi_assert(cfg);
memcpy(&(usb_uart->cfg_new), cfg, sizeof(UsbUartConfig));
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtCfgChange);
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtCfgChange);
}
void usb_uart_get_config(UsbUartBridge* usb_uart, UsbUartConfig* cfg) {

View File

@@ -19,7 +19,7 @@ ViewPort* gui_view_port_find_enabled(ViewPortArray_t array) {
void gui_update(Gui* gui) {
furi_assert(gui);
osThreadFlagsSet(gui->thread, GUI_THREAD_FLAG_DRAW);
furi_thread_flags_set(gui->thread_id, GUI_THREAD_FLAG_DRAW);
}
void gui_input_events_callback(const void* value, void* ctx) {
@@ -29,7 +29,7 @@ void gui_input_events_callback(const void* value, void* ctx) {
Gui* gui = ctx;
osMessageQueuePut(gui->input_queue, value, 0, osWaitForever);
osThreadFlagsSet(gui->thread, GUI_THREAD_FLAG_INPUT);
furi_thread_flags_set(gui->thread_id, GUI_THREAD_FLAG_INPUT);
}
// Only Fullscreen supports vertical display for now
@@ -471,7 +471,7 @@ void gui_set_lockdown(Gui* gui, bool lockdown) {
Gui* gui_alloc() {
Gui* gui = malloc(sizeof(Gui));
// Thread ID
gui->thread = osThreadGetId();
gui->thread_id = furi_thread_get_current_id();
// Allocate mutex
gui->mutex = osMutexNew(NULL);
furi_check(gui->mutex);
@@ -500,7 +500,8 @@ int32_t gui_srv(void* p) {
furi_record_create("gui", gui);
while(1) {
uint32_t flags = osThreadFlagsWait(GUI_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever);
uint32_t flags =
furi_thread_flags_wait(GUI_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever);
// Process and dispatch input
if(flags & GUI_THREAD_FLAG_INPUT) {
// Process till queue become empty
@@ -512,7 +513,7 @@ int32_t gui_srv(void* p) {
// Process and dispatch draw call
if(flags & GUI_THREAD_FLAG_DRAW) {
// Clear flags that arrived on input step
osThreadFlagsClear(GUI_THREAD_FLAG_DRAW);
furi_thread_flags_clear(GUI_THREAD_FLAG_DRAW);
gui_redraw(gui);
}
}

View File

@@ -57,7 +57,7 @@ ALGO_DEF(CanvasCallbackPairArray, CanvasCallbackPairArray_t);
/** Gui structure */
struct Gui {
// Thread and lock
osThreadId_t thread;
FuriThreadId thread_id;
osMutexId_t mutex;
// Layers and Canvas

View File

@@ -259,10 +259,10 @@ static int32_t browser_worker(void* context) {
string_t filename;
string_init(filename);
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtConfigChange);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange);
while(1) {
uint32_t flags = osThreadFlagsWait(WORKER_FLAGS_ALL, osFlagsWaitAny, osWaitForever);
uint32_t flags = furi_thread_flags_wait(WORKER_FLAGS_ALL, osFlagsWaitAny, osWaitForever);
furi_assert((flags & osFlagsError) == 0);
if(flags & WorkerEvtConfigChange) {
@@ -272,7 +272,7 @@ static int32_t browser_worker(void* context) {
}
idx_last_array_reset(browser->idx_last);
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtFolderEnter);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderEnter);
}
if(flags & WorkerEvtFolderEnter) {
@@ -369,7 +369,7 @@ BrowserWorker* file_browser_worker_alloc(string_t path, const char* filter_ext,
void file_browser_worker_free(BrowserWorker* browser) {
furi_assert(browser);
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtStop);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtStop);
furi_thread_join(browser->thread);
furi_thread_free(browser->thread);
@@ -423,30 +423,30 @@ void file_browser_worker_set_config(
string_set(browser->path_next, path);
string_set_str(browser->filter_extension, filter_ext);
browser->skip_assets = skip_assets;
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtConfigChange);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange);
}
void file_browser_worker_folder_enter(BrowserWorker* browser, string_t path, int32_t item_idx) {
furi_assert(browser);
string_set(browser->path_next, path);
browser->item_sel_idx = item_idx;
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtFolderEnter);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderEnter);
}
void file_browser_worker_folder_exit(BrowserWorker* browser) {
furi_assert(browser);
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtFolderExit);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderExit);
}
void file_browser_worker_folder_refresh(BrowserWorker* browser, int32_t item_idx) {
furi_assert(browser);
browser->item_sel_idx = item_idx;
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtFolderRefresh);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderRefresh);
}
void file_browser_worker_load(BrowserWorker* browser, uint32_t offset, uint32_t count) {
furi_assert(browser);
browser->load_offset = offset;
browser->load_count = count;
osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtLoad);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtLoad);
}

View File

@@ -36,7 +36,7 @@ void input_press_timer_callback(void* arg) {
void input_isr(void* _ctx) {
UNUSED(_ctx);
osThreadFlagsSet(input->thread, INPUT_THREAD_FLAG_ISR);
furi_thread_flags_set(input->thread_id, INPUT_THREAD_FLAG_ISR);
}
const char* input_get_key_name(InputKey key) {
@@ -66,7 +66,7 @@ const char* input_get_type_name(InputType type) {
int32_t input_srv() {
input = malloc(sizeof(Input));
input->thread = osThreadGetId();
input->thread_id = furi_thread_get_current_id();
input->event_pubsub = furi_pubsub_alloc();
furi_record_create("input_events", input->event_pubsub);
@@ -129,7 +129,7 @@ int32_t input_srv() {
if(is_changing) {
osDelay(1);
} else {
osThreadFlagsWait(INPUT_THREAD_FLAG_ISR, osFlagsWaitAny, osWaitForever);
furi_thread_flags_wait(INPUT_THREAD_FLAG_ISR, osFlagsWaitAny, osWaitForever);
}
}

View File

@@ -32,7 +32,7 @@ typedef struct {
/** Input state */
typedef struct {
osThreadId_t thread;
FuriThreadId thread_id;
FuriPubSub* event_pubsub;
InputPinState* pin_states;
Cli* cli;

View File

@@ -29,13 +29,9 @@ static bool
furi_thread_set_callback(
loader_instance->application_thread, loader_instance->application->app);
bool result = furi_thread_start(loader_instance->application_thread);
furi_thread_start(loader_instance->application_thread);
if(!result) {
loader_instance->application = NULL;
}
return result;
return true;
}
static void loader_menu_callback(void* _ctx, uint32_t index) {
@@ -300,7 +296,7 @@ static Loader* loader_alloc() {
UNUSED(loader_cli);
#endif
instance->loader_thread = osThreadGetId();
instance->loader_thread = furi_thread_get_current_id();
// Gui
instance->gui = furi_record_open("gui");
@@ -444,7 +440,7 @@ static void loader_build_submenu() {
void loader_show_menu() {
furi_assert(loader_instance);
osThreadFlagsSet(loader_instance->loader_thread, LOADER_THREAD_FLAG_SHOW_MENU);
furi_thread_flags_set(loader_instance->loader_thread, LOADER_THREAD_FLAG_SHOW_MENU);
}
void loader_update_menu() {
@@ -474,7 +470,8 @@ int32_t loader_srv(void* p) {
#endif
while(1) {
uint32_t flags = osThreadFlagsWait(LOADER_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever);
uint32_t flags =
furi_thread_flags_wait(LOADER_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever);
if(flags & LOADER_THREAD_FLAG_SHOW_MENU) {
menu_set_selected_item(loader_instance->primary_menu, 0);
view_dispatcher_switch_to_view(

View File

@@ -15,7 +15,7 @@
#include <assets_icons.h>
struct Loader {
osThreadId_t loader_thread;
FuriThreadId loader_thread;
const FlipperApplication* application;
FuriThread* application_thread;

View File

@@ -408,7 +408,7 @@ size_t
furi_assert(session);
size_t bytes_sent = xStreamBufferSend(session->stream, encoded_bytes, size, timeout);
osThreadFlagsSet(furi_thread_get_thread_id(session->thread), RpcEvtNewData);
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtNewData);
return bytes_sent;
}
@@ -441,7 +441,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
if(count == bytes_received) {
break;
} else {
flags = osThreadFlagsWait(RPC_ALL_EVENTS, osFlagsWaitAny, osWaitForever);
flags = furi_thread_flags_wait(RPC_ALL_EVENTS, osFlagsWaitAny, osWaitForever);
if(flags & RpcEvtDisconnect) {
if(xStreamBufferIsEmpty(session->stream)) {
session->terminate = true;
@@ -450,7 +450,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
break;
} else {
/* Save disconnect flag and continue reading buffer */
osThreadFlagsSet(furi_thread_get_thread_id(session->thread), RpcEvtDisconnect);
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtDisconnect);
}
} else if(flags & RpcEvtNewData) {
// Just wake thread up
@@ -643,7 +643,7 @@ void rpc_session_close(RpcSession* session) {
rpc_session_set_send_bytes_callback(session, NULL);
rpc_session_set_close_callback(session, NULL);
rpc_session_set_buffer_is_empty_callback(session, NULL);
osThreadFlagsSet(furi_thread_get_thread_id(session->thread), RpcEvtDisconnect);
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtDisconnect);
}
int32_t rpc_srv(void* p) {

View File

@@ -40,8 +40,7 @@ static void
memcpy(buffer, data, size);
osThreadFlagsSet(
furi_thread_get_thread_id(rpc_gui->transmit_thread), RpcGuiWorkerFlagTransmit);
furi_thread_flags_set(furi_thread_get_id(rpc_gui->transmit_thread), RpcGuiWorkerFlagTransmit);
}
static int32_t rpc_system_gui_screen_stream_frame_transmit_thread(void* context) {
@@ -50,7 +49,8 @@ static int32_t rpc_system_gui_screen_stream_frame_transmit_thread(void* context)
RpcGuiSystem* rpc_gui = (RpcGuiSystem*)context;
while(true) {
uint32_t flags = osThreadFlagsWait(RpcGuiWorkerFlagAny, osFlagsWaitAny, osWaitForever);
uint32_t flags =
furi_thread_flags_wait(RpcGuiWorkerFlagAny, osFlagsWaitAny, osWaitForever);
if(flags & RpcGuiWorkerFlagTransmit) {
rpc_send(rpc_gui->session, rpc_gui->transmit_frame);
}
@@ -117,8 +117,7 @@ static void rpc_system_gui_stop_screen_stream_process(const PB_Main* request, vo
gui_remove_framebuffer_callback(
rpc_gui->gui, rpc_system_gui_screen_stream_frame_callback, context);
// Stop and release worker thread
osThreadFlagsSet(
furi_thread_get_thread_id(rpc_gui->transmit_thread), RpcGuiWorkerFlagExit);
furi_thread_flags_set(furi_thread_get_id(rpc_gui->transmit_thread), RpcGuiWorkerFlagExit);
furi_thread_join(rpc_gui->transmit_thread);
furi_thread_free(rpc_gui->transmit_thread);
// Release frame
@@ -367,8 +366,7 @@ void rpc_system_gui_free(void* context) {
gui_remove_framebuffer_callback(
rpc_gui->gui, rpc_system_gui_screen_stream_frame_callback, context);
// Stop and release worker thread
osThreadFlagsSet(
furi_thread_get_thread_id(rpc_gui->transmit_thread), RpcGuiWorkerFlagExit);
furi_thread_flags_set(furi_thread_get_id(rpc_gui->transmit_thread), RpcGuiWorkerFlagExit);
furi_thread_join(rpc_gui->transmit_thread);
furi_thread_free(rpc_gui->transmit_thread);
// Release frame

View File

@@ -92,7 +92,9 @@ bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency) {
instance->worker_running = true;
instance->last_time_rx_data = 0;
res = furi_thread_start(instance->thread);
furi_thread_start(instance->thread);
res = true;
}
return res;
}

View File

@@ -72,18 +72,18 @@ static void u2f_hid_event_callback(HidU2fEvent ev, void* context) {
U2fHid* u2f_hid = context;
if(ev == HidU2fDisconnected)
osThreadFlagsSet(furi_thread_get_thread_id(u2f_hid->thread), WorkerEvtDisconnect);
furi_thread_flags_set(furi_thread_get_id(u2f_hid->thread), WorkerEvtDisconnect);
else if(ev == HidU2fConnected)
osThreadFlagsSet(furi_thread_get_thread_id(u2f_hid->thread), WorkerEvtConnect);
furi_thread_flags_set(furi_thread_get_id(u2f_hid->thread), WorkerEvtConnect);
else if(ev == HidU2fRequest)
osThreadFlagsSet(furi_thread_get_thread_id(u2f_hid->thread), WorkerEvtRequest);
furi_thread_flags_set(furi_thread_get_id(u2f_hid->thread), WorkerEvtRequest);
}
static void u2f_hid_lock_timeout_callback(void* context) {
furi_assert(context);
U2fHid* u2f_hid = context;
osThreadFlagsSet(furi_thread_get_thread_id(u2f_hid->thread), WorkerEvtUnlock);
furi_thread_flags_set(furi_thread_get_id(u2f_hid->thread), WorkerEvtUnlock);
}
static void u2f_hid_send_response(U2fHid* u2f_hid) {
@@ -198,7 +198,7 @@ static int32_t u2f_hid_worker(void* context) {
furi_hal_hid_u2f_set_callback(u2f_hid_event_callback, u2f_hid);
while(1) {
uint32_t flags = osThreadFlagsWait(
uint32_t flags = furi_thread_flags_wait(
WorkerEvtStop | WorkerEvtConnect | WorkerEvtDisconnect | WorkerEvtRequest,
osFlagsWaitAny,
osWaitForever);
@@ -292,7 +292,7 @@ U2fHid* u2f_hid_start(U2fData* u2f_inst) {
void u2f_hid_stop(U2fHid* u2f_hid) {
furi_assert(u2f_hid);
osThreadFlagsSet(furi_thread_get_thread_id(u2f_hid->thread), WorkerEvtStop);
furi_thread_flags_set(furi_thread_get_id(u2f_hid->thread), WorkerEvtStop);
furi_thread_join(u2f_hid->thread);
furi_thread_free(u2f_hid->thread);
free(u2f_hid);

View File

@@ -40,91 +40,3 @@ void test_furi_valuemutex() {
mu_check(delete_mutex(&valuemutex));
}
/*
TEST: concurrent access
1. Create holding record
2. Open it twice
3. Change value simultaneously in two app and check integrity
*/
// TODO this test broke because mutex in furi is not implemented
typedef struct {
// a and b must be equal
uint8_t a;
uint8_t b;
} ConcurrentValue;
void furi_concurent_app(void* p) {
ValueMutex* mutex = (ValueMutex*)p;
if(mutex == NULL) {
printf("cannot open mutex\r\n");
osThreadExit();
}
for(size_t i = 0; i < 10; i++) {
ConcurrentValue* value = (ConcurrentValue*)acquire_mutex_block(mutex);
if(value == NULL) {
printf("cannot take record\r\n");
release_mutex(mutex, value);
osThreadExit();
}
// emulate read-modify-write broken by context switching
uint8_t a = value->a;
uint8_t b = value->b;
a++;
b++;
furi_hal_delay_ms(2);
value->a = a;
value->b = b;
release_mutex(mutex, value);
}
osThreadExit();
}
void test_furi_concurrent_access() {
// TODO: reimplement or delete test
return;
/*
// 1. Create holding record
ConcurrentValue value = {.a = 0, .b = 0};
ValueMutex mutex;
mu_check(init_mutex(&mutex, &value, sizeof(value)));
// 3. Create second app for interact with it
FuriApp* second_app = furiac_start(furi_concurent_app, "furi concurent app", (void*)&mutex);
// 4. multiply ConcurrentValue::a
for(size_t i = 0; i < 4; i++) {
ConcurrentValue* value = (ConcurrentValue*)acquire_mutex_block(&mutex);
if(value == NULL) {
release_mutex(&mutex, value);
mu_fail("cannot take record\r\n");
}
// emulate read-modify-write broken by context switching
uint8_t a = value->a;
uint8_t b = value->b;
a++;
b++;
value->a = a;
furi_hal_delay_ms(10); // this is only for test, do not add delay between take/give in prod!
value->b = b;
release_mutex(&mutex, value);
}
furi_hal_delay_ms(50);
mu_assert_pointers_eq(second_app->handler, NULL);
mu_assert_int_eq(value.a, value.b);
mu_check(delete_mutex(&mutex));
*/
}

View File

@@ -33,10 +33,6 @@ MU_TEST(mu_test_furi_valuemutex) {
test_furi_valuemutex();
}
MU_TEST(mu_test_furi_concurrent_access) {
test_furi_concurrent_access();
}
MU_TEST(mu_test_furi_pubsub) {
test_furi_pubsub();
}
@@ -55,7 +51,6 @@ MU_TEST_SUITE(test_suite) {
// v2 tests
MU_RUN_TEST(mu_test_furi_create_open);
MU_RUN_TEST(mu_test_furi_valuemutex);
MU_RUN_TEST(mu_test_furi_concurrent_access);
MU_RUN_TEST(mu_test_furi_pubsub);
MU_RUN_TEST(mu_test_furi_memmgr);
}

View File

@@ -49,7 +49,7 @@ MU_TEST(storage_file_open_lock) {
furi_thread_set_stack_size(locker_thread, 2048);
furi_thread_set_context(locker_thread, semaphore);
furi_thread_set_callback(locker_thread, storage_file_locker);
mu_check(furi_thread_start(locker_thread));
furi_thread_start(locker_thread);
// wait for file lock
osSemaphoreAcquire(semaphore, osWaitForever);
@@ -139,7 +139,7 @@ MU_TEST(storage_dir_open_lock) {
furi_thread_set_stack_size(locker_thread, 2048);
furi_thread_set_context(locker_thread, semaphore);
furi_thread_set_callback(locker_thread, storage_dir_locker);
mu_check(furi_thread_start(locker_thread));
furi_thread_start(locker_thread);
// wait for dir lock
osSemaphoreAcquire(semaphore, osWaitForever);

View File

@@ -75,7 +75,7 @@ static bool subghz_decoder_test(const char* path, const char* name_decoder) {
bool level = level_duration_get_level(level_duration);
uint32_t duration = level_duration_get_duration(level_duration);
// Yield, to load data inside the worker
osThreadYield();
furi_thread_yield();
decoder->protocol->decoder->feed(decoder, level, duration);
} else {
break;
@@ -115,7 +115,7 @@ static bool subghz_decode_random_test(const char* path) {
bool level = level_duration_get_level(level_duration);
uint32_t duration = level_duration_get_duration(level_duration);
// Yield, to load data inside the worker
osThreadYield();
furi_thread_yield();
subghz_receiver_decode(receiver_handler, level, duration);
} else {
break;

View File

@@ -324,9 +324,9 @@ void update_task_set_progress_cb(UpdateTask* update_task, updateProgressCb cb, v
update_task->status_change_cb_state = state;
}
bool update_task_start(UpdateTask* update_task) {
void update_task_start(UpdateTask* update_task) {
furi_assert(update_task);
return furi_thread_start(update_task->thread);
furi_thread_start(update_task->thread);
}
bool update_task_is_running(UpdateTask* update_task) {

View File

@@ -74,7 +74,7 @@ void update_task_free(UpdateTask* update_task);
void update_task_set_progress_cb(UpdateTask* update_task, updateProgressCb cb, void* state);
bool update_task_start(UpdateTask* update_task);
void update_task_start(UpdateTask* update_task);
bool update_task_is_running(UpdateTask* update_task);