Refactor sleep handling and WASM task termination; consolidate platform-specific sleep functions and improve task cleanup logic

This commit is contained in:
Lukas Höppner
2026-08-12 14:25:21 +02:00
parent b04ba14891
commit bc78ce3534
6 changed files with 35 additions and 37 deletions
+10
View File
@@ -9,4 +9,14 @@ const nova64_io_interface_t *nova64_get_io_interface(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
-10
View File
@@ -20,16 +20,6 @@
#include <time.h>
#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 shutdown_requested = false;
static nova64_io_interface_t g_io_interface_storage;
+19 -25
View File
@@ -155,21 +155,21 @@ bool wasm_runner_start_program(
void wasm_runner_terminate(void) {
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++) {
if (g_wasm_slots[i].state == SLOT_RUNNING) {
g_wasm_slots[i].state = SLOT_STOPPING;
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);
}
}
}
/* Wait a short grace period for tasks to exit on their own. */
const TickType_t grace = pdMS_TO_TICKS(2000);
TickType_t start = xTaskGetTickCount();
bool any_running = true;
while (any_running) {
any_running = false;
// 2. Wait with HOST-Sleep (NATIVE C / C# thread-safe!)
int timeout_ms = 2000;
while (timeout_ms > 0) {
bool any_running = false;
for (int i = 0; i < MAX_WASM_TASKS; i++) {
if (g_wasm_slots[i].state != SLOT_FREE) {
any_running = true;
@@ -178,28 +178,22 @@ void wasm_runner_terminate(void) {
}
if (!any_running) {
break;
break; // All WASM tasks have terminated and cleaned up themselves!
}
if ((xTaskGetTickCount() - start) > grace) {
/* Force-delete any remaining FreeRTOS tasks */
for (int i = 0; i < MAX_WASM_TASKS; i++) {
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;
}
// IMPORTANT: Use Host-Sleep, NEVER use vTaskDelay on the C# thread!
nova64_host_sleep_ms(10);
timeout_ms -= 10;
}
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");
Binary file not shown.
+5 -1
View File
@@ -1,4 +1,8 @@
pushd "%~dp0"
@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
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
View File
@@ -5,7 +5,7 @@ pub fn main() void {
while (true) {
nova64.log("Hello from Zig!");
// nova64.yield();
// nova64.sleep(1000);
nova64.sleep(50);
}
}