Refactor sleep handling and WASM task termination; consolidate platform-specific sleep functions and improve task cleanup logic
This commit is contained in:
@@ -9,4 +9,14 @@ const nova64_io_interface_t *nova64_get_io_interface(void);
|
|||||||
|
|
||||||
void nova64_log_scheduler_state(void);
|
void nova64_log_scheduler_state(void);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#define nova64_host_sleep_ms(ms) Sleep(ms)
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#define nova64_host_sleep_ms(ms) usleep((ms) * 1000)
|
||||||
|
#else
|
||||||
|
#define nova64_host_sleep_ms(ms) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // NOVA64_INTERNAL_H
|
#endif // NOVA64_INTERNAL_H
|
||||||
@@ -20,16 +20,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <windows.h>
|
|
||||||
#define nova64_host_sleep_ms(ms) Sleep(ms)
|
|
||||||
#elif defined(__unix__) || defined(__APPLE__)
|
|
||||||
#include <unistd.h>
|
|
||||||
#define nova64_host_sleep_ms(ms) usleep((ms) * 1000)
|
|
||||||
#else
|
|
||||||
#define nova64_host_sleep_ms(ms) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile bool is_initialized = false;
|
volatile bool is_initialized = false;
|
||||||
volatile bool shutdown_requested = false;
|
volatile bool shutdown_requested = false;
|
||||||
static nova64_io_interface_t g_io_interface_storage;
|
static nova64_io_interface_t g_io_interface_storage;
|
||||||
|
|||||||
+19
-25
@@ -155,21 +155,21 @@ bool wasm_runner_start_program(
|
|||||||
void wasm_runner_terminate(void) {
|
void wasm_runner_terminate(void) {
|
||||||
nova64_log("Stopping all WASM tasks...\n");
|
nova64_log("Stopping all WASM tasks...\n");
|
||||||
|
|
||||||
|
// 1. Send stop signal to all running WASM instances
|
||||||
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
||||||
if (g_wasm_slots[i].state == SLOT_RUNNING) {
|
if (g_wasm_slots[i].state == SLOT_RUNNING) {
|
||||||
g_wasm_slots[i].state = SLOT_STOPPING;
|
g_wasm_slots[i].state = SLOT_STOPPING;
|
||||||
if (g_wasm_slots[i].module_inst) {
|
if (g_wasm_slots[i].module_inst) {
|
||||||
|
// Thread-safe: Only sets an abort flag internally in WAMR
|
||||||
wasm_runtime_terminate(g_wasm_slots[i].module_inst);
|
wasm_runtime_terminate(g_wasm_slots[i].module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait a short grace period for tasks to exit on their own. */
|
// 2. Wait with HOST-Sleep (NATIVE C / C# thread-safe!)
|
||||||
const TickType_t grace = pdMS_TO_TICKS(2000);
|
int timeout_ms = 2000;
|
||||||
TickType_t start = xTaskGetTickCount();
|
while (timeout_ms > 0) {
|
||||||
bool any_running = true;
|
bool any_running = false;
|
||||||
while (any_running) {
|
|
||||||
any_running = false;
|
|
||||||
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
||||||
if (g_wasm_slots[i].state != SLOT_FREE) {
|
if (g_wasm_slots[i].state != SLOT_FREE) {
|
||||||
any_running = true;
|
any_running = true;
|
||||||
@@ -178,28 +178,22 @@ void wasm_runner_terminate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!any_running) {
|
if (!any_running) {
|
||||||
break;
|
break; // All WASM tasks have terminated and cleaned up themselves!
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((xTaskGetTickCount() - start) > grace) {
|
// IMPORTANT: Use Host-Sleep, NEVER use vTaskDelay on the C# thread!
|
||||||
/* Force-delete any remaining FreeRTOS tasks */
|
nova64_host_sleep_ms(10);
|
||||||
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
timeout_ms -= 10;
|
||||||
if (g_wasm_slots[i].state != SLOT_FREE &&
|
}
|
||||||
g_wasm_slots[i].freertos_handle != NULL) {
|
|
||||||
nova64_log("Force-deleting WASM task %d\n", i);
|
|
||||||
vTaskDelete(g_wasm_slots[i].freertos_handle);
|
|
||||||
g_wasm_slots[i].freertos_handle = NULL;
|
|
||||||
}
|
|
||||||
/* Mark slot free even if we couldn't fully clean up module state to
|
|
||||||
* avoid blocking shutdown; it's better to free the native thread. */
|
|
||||||
g_wasm_slots[i].module_inst = NULL;
|
|
||||||
g_wasm_slots[i].exec_env = NULL;
|
|
||||||
g_wasm_slots[i].state = SLOT_FREE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
// 3. If after 2s a task is still hanging: ONLY clean up flags,
|
||||||
|
// NEVER call vTaskDelete from outside!
|
||||||
|
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
||||||
|
if (g_wasm_slots[i].state != SLOT_FREE) {
|
||||||
|
nova64_log("Warning: Task slot %d failed to exit gracefully.\n", i);
|
||||||
|
g_wasm_slots[i].state = SLOT_FREE;
|
||||||
|
g_wasm_slots[i].freertos_handle = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nova64_log("All WASM tasks successfully stopped.\n");
|
nova64_log("All WASM tasks successfully stopped.\n");
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +1,8 @@
|
|||||||
|
pushd "%~dp0"
|
||||||
|
|
||||||
@REM tinygo build -o ../simulator/sd/slot0/init.wasm -target wasm-unknown init.go
|
@REM tinygo build -o ../simulator/sd/slot0/init.wasm -target wasm-unknown init.go
|
||||||
|
|
||||||
@REM zig build-exe init.zig -target wasm32-freestanding -fno-entry -O ReleaseSmall -femit-bin=../simulator/sd/slot0/init.wasm
|
@REM zig build-exe init.zig -target wasm32-freestanding -fno-entry -O ReleaseSmall -femit-bin=../simulator/sd/slot0/init.wasm
|
||||||
zig build-exe init.zig -target wasm32-freestanding -O ReleaseSmall -femit-bin=../simulator/sd/slot0/init.wasm
|
zig build-exe init.zig -target wasm32-freestanding -O ReleaseSmall -femit-bin=../simulator/sd/slot0/init.wasm
|
||||||
|
|
||||||
|
popd
|
||||||
+1
-1
@@ -5,7 +5,7 @@ pub fn main() void {
|
|||||||
while (true) {
|
while (true) {
|
||||||
nova64.log("Hello from Zig!");
|
nova64.log("Hello from Zig!");
|
||||||
// nova64.yield();
|
// nova64.yield();
|
||||||
// nova64.sleep(1000);
|
nova64.sleep(50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user