From 8125f78f70dbfbf2213f55d4494f4192c1b3a347 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 08:39:33 +0200 Subject: [PATCH 01/26] Blinky works Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_api.c | 7 +- src/ocre/api/ocre_common.c | 706 +++++++++++++++++- src/ocre/api/ocre_common.h | 90 ++- .../container_supervisor/cs_sm_impl.c | 7 +- src/ocre/ocre_timers/ocre_timer.c | 178 ++++- src/shared/platform/posix/core_internal.h | 1 + src/shared/platform/posix/ocre_internal.cmake | 3 + .../platform/zephyr/ocre_internal.cmake | 7 +- 8 files changed, 964 insertions(+), 35 deletions(-) diff --git a/src/ocre/api/ocre_api.c b/src/ocre/api/ocre_api.c index b6aa95de..f9f9d8db 100644 --- a/src/ocre/api/ocre_api.c +++ b/src/ocre/api/ocre_api.c @@ -20,9 +20,10 @@ #include "ocre_api.h" -#ifdef CONFIG_OCRE_TIMER -#include "../ocre_timers/ocre_timer.h" -#endif +// Timer functionality is now integrated into ocre_common.c +// #ifdef CONFIG_OCRE_TIMER +// #include "../ocre_timers/ocre_timer.h" +// #endif #include "ocre/utils/utils.h" diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 6d26d16e..d8f1b05e 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -7,27 +7,48 @@ #include #include "ocre_core_external.h" +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ZEPHYR #include #include #include #include #include -#include -#include LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); #include +#include +#else /* POSIX */ +#include +#include +#include +#include +#include +/* POSIX logging macros are already defined in core_internal.h */ +#endif + #include "../../../../../wasm-micro-runtime/core/iwasm/include/lib_export.h" #include "bh_log.h" -#include "../ocre_timers/ocre_timer.h" + +#ifdef CONFIG_ZEPHYR #include "../ocre_gpio/ocre_gpio.h" #include "../ocre_messaging/ocre_messaging.h" +#endif + #include "ocre_common.h" -#include -// Place queue buffer in a dedicated section with alignments + +/* Platform-specific abstractions */ +#ifdef CONFIG_ZEPHYR + #define SIZE_OCRE_EVENT_BUFFER 32 __attribute__((section(".noinit.ocre_event_queue"), aligned(8))) char ocre_event_queue_buffer[SIZE_OCRE_EVENT_BUFFER * sizeof(ocre_event_t)]; -char *ocre_event_queue_buffer_ptr = ocre_event_queue_buffer; // Pointer for validation +char *ocre_event_queue_buffer_ptr = ocre_event_queue_buffer; K_MSGQ_DEFINE(ocre_event_queue, sizeof(ocre_event_t), SIZE_OCRE_EVENT_BUFFER, 4); bool ocre_event_queue_initialized = false; @@ -41,6 +62,185 @@ typedef struct module_node { static sys_slist_t module_registry; static struct k_mutex registry_mutex; +/* Zephyr-specific macros */ +#define OCRE_MALLOC(size) k_malloc(size) +#define OCRE_FREE(ptr) k_free(ptr) +#define OCRE_UPTIME_GET() k_uptime_get_32() +#define OCRE_MUTEX_LOCK(mutex) k_mutex_lock(mutex, K_FOREVER) +#define OCRE_MUTEX_UNLOCK(mutex) k_mutex_unlock(mutex) +#define OCRE_MUTEX_INIT(mutex) k_mutex_init(mutex) +#define OCRE_SPINLOCK_LOCK(lock) k_spin_lock(lock) +#define OCRE_SPINLOCK_UNLOCK(lock, key) k_spin_unlock(lock, key) + +#else /* POSIX */ + +#define SIZE_OCRE_EVENT_BUFFER 32 + +/* POSIX simple linked list implementation */ +typedef struct posix_snode { + struct posix_snode *next; +} posix_snode_t; + +typedef struct { + posix_snode_t *head; + posix_snode_t *tail; +} posix_slist_t; + +/* POSIX message queue simulation */ +typedef struct { + ocre_event_t *buffer; + size_t size; + size_t count; + size_t head; + size_t tail; + pthread_mutex_t mutex; + pthread_cond_t cond; +} posix_msgq_t; + +/* POSIX spinlock simulation using mutex */ +typedef struct { + pthread_mutex_t mutex; +} posix_spinlock_t; + +typedef int posix_spinlock_key_t; + +static char ocre_event_queue_buffer[SIZE_OCRE_EVENT_BUFFER * sizeof(ocre_event_t)]; +char *ocre_event_queue_buffer_ptr = ocre_event_queue_buffer; + +static posix_msgq_t ocre_event_queue; +bool ocre_event_queue_initialized = false; +static posix_spinlock_t ocre_event_queue_lock; + +typedef struct module_node { + ocre_module_context_t ctx; + posix_snode_t node; +} module_node_t; + +static posix_slist_t module_registry; +static pthread_mutex_t registry_mutex; + +/* POSIX-specific macros */ +#define OCRE_MALLOC(size) malloc(size) +#define OCRE_FREE(ptr) free(ptr) +#define OCRE_UPTIME_GET() posix_uptime_get() +#define OCRE_MUTEX_LOCK(mutex) pthread_mutex_lock(mutex) +#define OCRE_MUTEX_UNLOCK(mutex) pthread_mutex_unlock(mutex) +#define OCRE_MUTEX_INIT(mutex) pthread_mutex_init(mutex, NULL) +#define OCRE_SPINLOCK_LOCK(lock) posix_spinlock_lock(lock) +#define OCRE_SPINLOCK_UNLOCK(lock, key) posix_spinlock_unlock(lock, key) + +/* POSIX error codes compatibility */ +#ifndef EINVAL +#define EINVAL 22 +#endif +#ifndef ENOMSG +#define ENOMSG 42 +#endif +#ifndef EPERM +#define EPERM 1 +#endif +#ifndef ENOENT +#define ENOENT 2 +#endif +#ifndef ENOMEM +#define ENOMEM 12 +#endif + +/* POSIX helper functions */ +static uint32_t posix_uptime_get(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint32_t)(ts.tv_sec * 1000 + ts.tv_nsec / 1000000); +} + +static posix_spinlock_key_t posix_spinlock_lock(posix_spinlock_t *lock) { + pthread_mutex_lock(&lock->mutex); + return 0; +} + +static void posix_spinlock_unlock(posix_spinlock_t *lock, posix_spinlock_key_t key) { + (void)key; + pthread_mutex_unlock(&lock->mutex); +} + +static void posix_slist_init(posix_slist_t *list) { + list->head = NULL; + list->tail = NULL; +} + +static void posix_slist_append(posix_slist_t *list, posix_snode_t *node) { + node->next = NULL; + if (list->tail) { + list->tail->next = node; + } else { + list->head = node; + } + list->tail = node; +} + +static void posix_slist_remove(posix_slist_t *list, posix_snode_t *prev, posix_snode_t *node) { + if (prev) { + prev->next = node->next; + } else { + list->head = node->next; + } + if (list->tail == node) { + list->tail = prev; + } +} + +static int posix_msgq_init(posix_msgq_t *msgq, size_t item_size, size_t max_items) { + msgq->buffer = (ocre_event_t *)ocre_event_queue_buffer; + msgq->size = max_items; + msgq->count = 0; + msgq->head = 0; + msgq->tail = 0; + pthread_mutex_init(&msgq->mutex, NULL); + pthread_cond_init(&msgq->cond, NULL); + return 0; +} + +static int posix_msgq_peek(posix_msgq_t *msgq, ocre_event_t *event) { + if (msgq->count == 0) { + return -ENOMSG; + } + *event = msgq->buffer[msgq->head]; + return 0; +} + +static int posix_msgq_get(posix_msgq_t *msgq, ocre_event_t *event) { + if (msgq->count == 0) { + return -ENOENT; + } + *event = msgq->buffer[msgq->head]; + msgq->head = (msgq->head + 1) % msgq->size; + msgq->count--; + return 0; +} + +static int posix_msgq_put(posix_msgq_t *msgq, const ocre_event_t *event) { + if (msgq->count >= msgq->size) { + return -ENOMEM; + } + msgq->buffer[msgq->tail] = *event; + msgq->tail = (msgq->tail + 1) % msgq->size; + msgq->count++; + return 0; +} + +#define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(list, var, tmp, member) \ + for (var = (module_node_t *)((list)->head), \ + tmp = var ? (module_node_t *)(var->node.next) : NULL; \ + var; \ + var = tmp, tmp = tmp ? (module_node_t *)(tmp->node.next) : NULL) + +#define SYS_SLIST_FOR_EACH_CONTAINER(list, var, member) \ + for (var = (module_node_t *)((list)->head); \ + var; \ + var = (module_node_t *)(var->node.next)) + +#endif /* CONFIG_ZEPHYR */ + static struct cleanup_handler { ocre_resource_type_t type; ocre_cleanup_handler_t handler; @@ -95,10 +295,12 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o } ocre_event_t event; + int ret; + +#ifdef CONFIG_ZEPHYR k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); - int ret = k_msgq_peek(&ocre_event_queue, &event); + ret = k_msgq_peek(&ocre_event_queue, &event); if (ret != 0) { - // k_msg_peek returns either 0, or -ENOMSG if empty k_spin_unlock(&ocre_event_queue_lock, key); return -ENOMSG; } @@ -113,6 +315,25 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o k_spin_unlock(&ocre_event_queue_lock, key); return -ENOENT; } +#else /* POSIX */ + posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); + ret = posix_msgq_peek(&ocre_event_queue, &event); + if (ret != 0) { + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + return -ENOMSG; + } + + if (event.owner != module_inst) { + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + return -EPERM; + } + + ret = posix_msgq_get(&ocre_event_queue, &event); + if (ret != 0) { + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + return -ENOENT; + } +#endif // Send event correctly to WASM switch (event.type) { @@ -163,12 +384,20 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o ================================= */ default: { +#ifdef CONFIG_ZEPHYR k_spin_unlock(&ocre_event_queue_lock, key); +#else + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); +#endif LOG_ERR("Invalid event type: %u", event.type); return -EINVAL; } } +#ifdef CONFIG_ZEPHYR k_spin_unlock(&ocre_event_queue_lock, key); +#else + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); +#endif return 0; } @@ -178,6 +407,8 @@ int ocre_common_init(void) { LOG_INF("Common system already initialized"); return 0; } + +#ifdef CONFIG_ZEPHYR k_mutex_init(®istry_mutex); sys_slist_init(&module_registry); if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { @@ -189,6 +420,17 @@ int ocre_common_init(void) { while (k_msgq_get(&ocre_event_queue, &dummy, K_NO_WAIT) == 0) { LOG_INF("Purged stale event from queue"); } +#else /* POSIX */ + OCRE_MUTEX_INIT(®istry_mutex); + posix_slist_init(&module_registry); + if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { + LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); + return -EINVAL; + } + posix_msgq_init(&ocre_event_queue, sizeof(ocre_event_t), SIZE_OCRE_EVENT_BUFFER); + pthread_mutex_init(&ocre_event_queue_lock.mutex, NULL); +#endif + ocre_event_queue_initialized = true; #if EVENT_THREAD_POOL_SIZE > 0 LOG_INF("ocre_event_queue initialized at %p, size=%d, buffer=%p", (void *)&ocre_event_queue, sizeof(ocre_event_t), @@ -208,6 +450,10 @@ int ocre_common_init(void) { #endif initialized = true; common_initialized = true; + + /* Initialize timer system as part of common initialization */ + ocre_timer_init(); + LOG_INF("OCRE common initialized successfully"); return 0; } @@ -241,7 +487,7 @@ int ocre_register_module(wasm_module_inst_t module_inst) { LOG_ERR("Null module instance"); return -EINVAL; } - module_node_t *node = k_malloc(sizeof(module_node_t)); + module_node_t *node = OCRE_MALLOC(sizeof(module_node_t)); if (!node) { LOG_ERR("Failed to allocate module node"); return -ENOMEM; @@ -250,16 +496,24 @@ int ocre_register_module(wasm_module_inst_t module_inst) { node->ctx.exec_env = wasm_runtime_create_exec_env(module_inst, OCRE_WASM_STACK_SIZE); if (!node->ctx.exec_env) { LOG_ERR("Failed to create exec env for module %p", (void *)module_inst); - k_free(node); + OCRE_FREE(node); return -ENOMEM; } node->ctx.in_use = true; - node->ctx.last_activity = k_uptime_get_32(); + node->ctx.last_activity = OCRE_UPTIME_GET(); memset(node->ctx.resource_count, 0, sizeof(node->ctx.resource_count)); memset(node->ctx.dispatchers, 0, sizeof(node->ctx.dispatchers)); + +#ifdef CONFIG_ZEPHYR k_mutex_lock(®istry_mutex, K_FOREVER); sys_slist_append(&module_registry, &node->node); k_mutex_unlock(®istry_mutex); +#else + OCRE_MUTEX_LOCK(®istry_mutex); + posix_slist_append(&module_registry, &node->node); + OCRE_MUTEX_UNLOCK(®istry_mutex); +#endif + LOG_INF("Module registered: %p", (void *)module_inst); return 0; } @@ -269,6 +523,8 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { LOG_ERR("Null module instance"); return; } + +#ifdef CONFIG_ZEPHYR k_mutex_lock(®istry_mutex, K_FOREVER); module_node_t *node, *tmp; SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { @@ -284,6 +540,25 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { } } k_mutex_unlock(®istry_mutex); +#else + OCRE_MUTEX_LOCK(®istry_mutex); + module_node_t *node, *tmp; + module_node_t *prev = NULL; + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { + if (node->ctx.inst == module_inst) { + ocre_cleanup_module_resources(module_inst); + if (node->ctx.exec_env) { + wasm_runtime_destroy_exec_env(node->ctx.exec_env); + } + posix_slist_remove(&module_registry, prev ? &prev->node : NULL, &node->node); + OCRE_FREE(node); + LOG_INF("Module unregistered: %p", (void *)module_inst); + break; + } + prev = node; + } + OCRE_MUTEX_UNLOCK(®istry_mutex); +#endif } ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { @@ -291,16 +566,39 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { LOG_ERR("Null module instance"); return NULL; } + + LOG_DBG("Looking for module context: %p", (void *)module_inst); + + int count = 0; + +#ifdef CONFIG_ZEPHYR k_mutex_lock(®istry_mutex, K_FOREVER); - module_node_t *node; - SYS_SLIST_FOR_EACH_CONTAINER(&module_registry, node, node) { + for (sys_snode_t *current = module_registry.head; current != NULL; current = current->next) { + module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); + LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { node->ctx.last_activity = k_uptime_get_32(); k_mutex_unlock(®istry_mutex); + LOG_DBG("Found module context for %p", (void *)module_inst); return &node->ctx; } } k_mutex_unlock(®istry_mutex); +#else + OCRE_MUTEX_LOCK(®istry_mutex); + for (posix_snode_t *current = module_registry.head; current != NULL; current = current->next) { + module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); + LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); + if (node->ctx.inst == module_inst) { + node->ctx.last_activity = OCRE_UPTIME_GET(); + OCRE_MUTEX_UNLOCK(®istry_mutex); + LOG_DBG("Found module context for %p", (void *)module_inst); + return &node->ctx; + } + } + OCRE_MUTEX_UNLOCK(®istry_mutex); +#endif + LOG_ERR("Module context not found for %p", (void *)module_inst); return NULL; } @@ -311,7 +609,13 @@ int ocre_register_dispatcher(wasm_exec_env_t exec_env, ocre_resource_type_t type function_name ? function_name : "null"); return -EINVAL; } + + LOG_DBG("ocre_register_dispatcher: exec_env=%p, type=%d, func=%s", (void *)exec_env, type, function_name); + LOG_DBG("current_module_tls = %p", current_module_tls ? (void *)*current_module_tls : NULL); + wasm_module_inst_t module_inst = current_module_tls ? *current_module_tls : wasm_runtime_get_module_inst(exec_env); + LOG_DBG("Retrieved module_inst = %p", (void *)module_inst); + if (!module_inst) { LOG_ERR("No module instance for event type %d", type); return -EINVAL; @@ -327,9 +631,17 @@ int ocre_register_dispatcher(wasm_exec_env_t exec_env, ocre_resource_type_t type LOG_ERR("Function %s not found in module %p", function_name, (void *)module_inst); return -EINVAL; } +#ifdef CONFIG_ZEPHYR k_mutex_lock(®istry_mutex, K_FOREVER); +#else + OCRE_MUTEX_LOCK(®istry_mutex); +#endif ctx->dispatchers[type] = func; +#ifdef CONFIG_ZEPHYR k_mutex_unlock(®istry_mutex); +#else + OCRE_MUTEX_UNLOCK(®istry_mutex); +#endif LOG_INF("Registered dispatcher for type %d: %s", type, function_name); return 0; } @@ -342,9 +654,17 @@ uint32_t ocre_get_resource_count(wasm_module_inst_t module_inst, ocre_resource_t void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT) { +#ifdef CONFIG_ZEPHYR k_mutex_lock(®istry_mutex, K_FOREVER); +#else + OCRE_MUTEX_LOCK(®istry_mutex); +#endif ctx->resource_count[type]++; +#ifdef CONFIG_ZEPHYR k_mutex_unlock(®istry_mutex); +#else + OCRE_MUTEX_UNLOCK(®istry_mutex); +#endif LOG_INF("Incremented resource count: type=%d, count=%d", type, ctx->resource_count[type]); } } @@ -352,9 +672,17 @@ void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource void ocre_decrement_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT && ctx->resource_count[type] > 0) { +#ifdef CONFIG_ZEPHYR k_mutex_lock(®istry_mutex, K_FOREVER); +#else + OCRE_MUTEX_LOCK(®istry_mutex); +#endif ctx->resource_count[type]--; +#ifdef CONFIG_ZEPHYR k_mutex_unlock(®istry_mutex); +#else + OCRE_MUTEX_UNLOCK(®istry_mutex); +#endif LOG_INF("Decremented resource count: type=%d, count=%d", type, ctx->resource_count[type]); } } @@ -370,3 +698,355 @@ void ocre_cleanup_module_resources(wasm_module_inst_t module_inst) { wasm_module_inst_t ocre_get_current_module(void) { return current_module_tls ? *current_module_tls : NULL; } + +/* ========== OCRE TIMER FUNCTIONALITY ========== */ + +#include "ocre_common.h" + +/* Timer type definition */ +typedef uint32_t ocre_timer_t; + +/* Platform-specific timer structures */ +#ifdef CONFIG_ZEPHYR +// Compact timer structure for Zephyr +typedef struct { + uint32_t in_use: 1; + uint32_t id: 8; // Up to 256 timers + uint32_t interval: 16; // Up to 65s intervals + uint32_t periodic: 1; + struct k_timer timer; + wasm_module_inst_t owner; +} ocre_timer_internal; + +#else /* POSIX */ +// POSIX timer structure +typedef struct { + uint32_t in_use: 1; + uint32_t id: 8; // Up to 256 timers + uint32_t interval: 16; // Up to 65s intervals + uint32_t periodic: 1; + timer_t timer; + pthread_t thread; + bool thread_running; + wasm_module_inst_t owner; +} ocre_timer_internal; + +/* POSIX timer thread function - not used currently */ +#endif + +#ifndef CONFIG_MAX_TIMER +#define CONFIG_MAX_TIMERS 5 +#endif + +// Static data +static ocre_timer_internal timers[CONFIG_MAX_TIMERS]; +static bool timer_system_initialized = false; + +#ifdef CONFIG_ZEPHYR +static void timer_callback_wrapper(struct k_timer *timer); +#else +static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc); +static void posix_send_timer_event(int timer_id); +#endif + +void ocre_timer_init(void) { + if (timer_system_initialized) { + LOG_INF("Timer system already initialized"); + return; + } + + if (!common_initialized && ocre_common_init() != 0) { + LOG_ERR("Failed to initialize common subsystem"); + return; + } + +#ifndef CONFIG_ZEPHYR + // Setup POSIX signal handler for timer callbacks + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = posix_timer_signal_handler; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) == -1) { + LOG_ERR("Failed to setup POSIX timer signal handler"); + return; + } +#endif + + ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_TIMER, ocre_timer_cleanup_container); + timer_system_initialized = true; + LOG_INF("Timer system initialized"); +} + +int ocre_timer_create(wasm_exec_env_t exec_env, int id) { + wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); + if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { + LOG_ERR("Invalid module %p or timer ID %d (max: %d)", (void *)module, id, CONFIG_MAX_TIMERS); + return -EINVAL; + } + + ocre_timer_internal *timer = &timers[id - 1]; + if (timer->in_use) { + LOG_ERR("Timer ID %d already in use", id); + return -EBUSY; + } + + timer->id = id; + timer->owner = module; + timer->in_use = 1; + +#ifdef CONFIG_ZEPHYR + k_timer_init(&timer->timer, timer_callback_wrapper, NULL); +#else + struct sigevent sev; + memset(&sev, 0, sizeof(sev)); + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIGALRM; + sev.sigev_value.sival_int = id; + + if (timer_create(CLOCK_REALTIME, &sev, &timer->timer) == -1) { + LOG_ERR("Failed to create POSIX timer %d", id); + timer->in_use = 0; + return -EINVAL; + } + timer->thread_running = false; +#endif + + ocre_increment_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); + LOG_INF("Created timer %d for module %p", id, (void *)module); + return 0; +} + +int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id) { + wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); + if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { + LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); + return -EINVAL; + } + + ocre_timer_internal *timer = &timers[id - 1]; + if (!timer->in_use || timer->owner != module) { + LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); + return -EINVAL; + } + +#ifdef CONFIG_ZEPHYR + k_timer_stop(&timer->timer); +#else + timer_delete(&timer->timer); + if (timer->thread_running) { + pthread_cancel(timer->thread); + timer->thread_running = false; + } +#endif + + timer->in_use = 0; + timer->owner = NULL; + ocre_decrement_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); + LOG_INF("Deleted timer %d", id); + return 0; +} + +int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, int is_periodic) { + wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); + if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { + LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); + return -EINVAL; + } + + ocre_timer_internal *timer = &timers[id - 1]; + if (!timer->in_use || timer->owner != module) { + LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); + return -EINVAL; + } + + if (interval <= 0 || interval > 65535) { + LOG_ERR("Invalid interval %dms (must be 1-65535ms)", interval); + return -EINVAL; + } + + timer->interval = interval; + timer->periodic = is_periodic; + +#ifdef CONFIG_ZEPHYR + k_timeout_t duration = K_MSEC(interval); + k_timeout_t period = is_periodic ? duration : K_NO_WAIT; + k_timer_start(&timer->timer, duration, period); +#else + struct itimerspec its; + its.it_value.tv_sec = interval / 1000; + its.it_value.tv_nsec = (interval % 1000) * 1000000; + + if (is_periodic) { + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + } else { + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + } + + if (timer_settime(timer->timer, 0, &its, NULL) == -1) { + LOG_ERR("Failed to start POSIX timer %d", id); + return -EINVAL; + } +#endif + + LOG_INF("Started timer %d with interval %dms, periodic=%d", id, interval, is_periodic); + return 0; +} + +int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id) { + wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); + if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { + LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); + return -EINVAL; + } + + ocre_timer_internal *timer = &timers[id - 1]; + if (!timer->in_use || timer->owner != module) { + LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); + return -EINVAL; + } + +#ifdef CONFIG_ZEPHYR + k_timer_stop(&timer->timer); +#else + struct itimerspec its; + memset(&its, 0, sizeof(its)); + timer_settime(timer->timer, 0, &its, NULL); +#endif + + LOG_INF("Stopped timer %d", id); + return 0; +} + +int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id) { + wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); + if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { + LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); + return -EINVAL; + } + + ocre_timer_internal *timer = &timers[id - 1]; + if (!timer->in_use || timer->owner != module) { + LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); + return -EINVAL; + } + + int remaining; +#ifdef CONFIG_ZEPHYR + remaining = k_ticks_to_ms_floor32(k_timer_remaining_ticks(&timer->timer)); +#else + struct itimerspec its; + if (timer_gettime(timer->timer, &its) == -1) { + LOG_ERR("Failed to get remaining time for timer %d", id); + return -EINVAL; + } + remaining = its.it_value.tv_sec * 1000 + its.it_value.tv_nsec / 1000000; +#endif + + LOG_INF("Timer %d remaining time: %dms", id, remaining); + return remaining; +} + +void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { + if (!module_inst) { + LOG_ERR("Invalid module instance for cleanup"); + return; + } + + for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { + if (timers[i].in_use && timers[i].owner == module_inst) { +#ifdef CONFIG_ZEPHYR + k_timer_stop(&timers[i].timer); +#else + timer_delete(&timers[i].timer); + if (timers[i].thread_running) { + pthread_cancel(timers[i].thread); + timers[i].thread_running = false; + } +#endif + timers[i].in_use = 0; + timers[i].owner = NULL; + ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_TIMER); + LOG_INF("Cleaned up timer %d for module %p", i + 1, (void *)module_inst); + } + } + LOG_INF("Cleaned up timer resources for module %p", (void *)module_inst); +} + +#ifdef CONFIG_ZEPHYR +static void timer_callback_wrapper(struct k_timer *timer) { + if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { + LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); + return; + } + if (!timer) { + LOG_ERR("Null timer pointer in callback"); + return; + } + if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { + LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); + return; + } + LOG_DBG("Timer callback for timer %p", (void *)timer); + LOG_DBG("ocre_event_queue at %p, buffer at %p", (void *)&ocre_event_queue, (void *)ocre_event_queue_buffer_ptr); + for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { + if (timers[i].in_use && &timers[i].timer == timer && timers[i].owner) { + ocre_event_t event; + event.type = OCRE_RESOURCE_TYPE_TIMER; + event.data.timer_event.timer_id = timers[i].id; + event.owner = timers[i].owner; + + LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, event.data.timer_event.timer_id, + (void *)timers[i].owner); + LOG_DBG("Event address: %p, Queue buffer: %p", (void *)&event, (void *)ocre_event_queue_buffer_ptr); + k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); + if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { + LOG_ERR("Failed to queue timer event for timer %d", timers[i].id); + } else { + LOG_DBG("Queued timer event for timer %d", timers[i].id); + } + k_spin_unlock(&ocre_event_queue_lock, key); + } + } +} + +#else /* POSIX */ + +static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc) { + (void)sig; + (void)uc; + if (si && si->si_value.sival_int > 0 && si->si_value.sival_int <= CONFIG_MAX_TIMERS) { + posix_send_timer_event(si->si_value.sival_int); + } +} + +static void posix_send_timer_event(int timer_id) { + if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { + LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); + return; + } + + int index = timer_id - 1; + if (index < 0 || index >= CONFIG_MAX_TIMERS || !timers[index].in_use) { + LOG_ERR("Invalid timer ID %d in callback", timer_id); + return; + } + + ocre_event_t event; + event.type = OCRE_RESOURCE_TYPE_TIMER; + event.data.timer_event.timer_id = timer_id; + event.owner = timers[index].owner; + + LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer_id, (void *)timers[index].owner); + + posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); + if (posix_msgq_put(&ocre_event_queue, &event) != 0) { + LOG_ERR("Failed to queue timer event for timer %d", timer_id); + } else { + LOG_DBG("Queued timer event for timer %d", timer_id); + } + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); +} + +#endif diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index 6f0c6671..1c462770 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -8,26 +8,38 @@ #ifndef OCRE_COMMON_H #define OCRE_COMMON_H +#include +#include +#include + +/* Platform-specific includes */ +#ifdef CONFIG_ZEPHYR #include #include -#include #include "../ocre_messaging/ocre_messaging.h" +#else +#include +/* Forward declarations for POSIX messaging types */ +struct ocre_messaging_event; +#endif #define OCRE_EVENT_THREAD_STACK_SIZE 2048 #define OCRE_EVENT_THREAD_PRIORITY 5 #define OCRE_WASM_STACK_SIZE 16384 #define EVENT_THREAD_POOL_SIZE 0 - extern bool common_initialized; extern bool ocre_event_queue_initialized; extern __thread wasm_module_inst_t *current_module_tls; +extern char *ocre_event_queue_buffer_ptr; // Defined in ocre_common.c - +/* Platform-specific external declarations */ +#ifdef CONFIG_ZEPHYR extern struct k_msgq ocre_event_queue; // Defined in ocre_common.c -extern bool ocre_event_queue_initialized; // Defined in ocre_common.c extern struct k_spinlock ocre_event_queue_lock; // Defined in ocre_common.c -extern char *ocre_event_queue_buffer_ptr; // Defined in ocre_common.c +#else +/* POSIX equivalents will be defined in the .c file */ +#endif /** @@ -205,4 +217,70 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o void ocre_common_shutdown(void); -#endif /* OCRE_COMMON_H */ \ No newline at end of file +/* ========== OCRE TIMER FUNCTIONALITY ========== */ + +#ifndef OCRE_TIMER_T_DEFINED +#define OCRE_TIMER_T_DEFINED +typedef uint32_t ocre_timer_t; +#endif + +/** + * @brief Initialize the timer system. + */ +void ocre_timer_init(void); + +/** + * @brief Create a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return 0 on success, negative error code on failure. + */ +int ocre_timer_create(wasm_exec_env_t exec_env, int id); + +/** + * @brief Delete a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return 0 on success, negative error code on failure. + */ +int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id); + +/** + * @brief Start a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @param interval Timer interval in milliseconds. + * @param is_periodic Whether the timer is periodic. + * @return 0 on success, negative error code on failure. + */ +int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, int is_periodic); + +/** + * @brief Stop a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return 0 on success, negative error code on failure. + */ +int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id); + +/** + * @brief Get remaining time for a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return Remaining time in milliseconds, or negative error code on failure. + */ +int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id); + +/** + * @brief Cleanup timer resources for a module. + * + * @param module_inst WASM module instance. + */ +void ocre_timer_cleanup_container(wasm_module_inst_t module_inst); + +#endif /* OCRE_COMMON_H */ diff --git a/src/ocre/components/container_supervisor/cs_sm_impl.c b/src/ocre/components/container_supervisor/cs_sm_impl.c index 8b96f4a6..9ba3aafa 100644 --- a/src/ocre/components/container_supervisor/cs_sm_impl.c +++ b/src/ocre/components/container_supervisor/cs_sm_impl.c @@ -7,9 +7,10 @@ #include #include "ocre_core_external.h" -#ifdef CONFIG_OCRE_TIMER -#include "ocre_timers/ocre_timer.h" -#endif +// Timer functionality is now integrated into ocre_common.c +// #ifdef CONFIG_OCRE_TIMER +// #include "ocre_timers/ocre_timer.h" +// #endif #ifdef CONFIG_OCRE_GPIO #include "ocre_gpio/ocre_gpio.h" #endif diff --git a/src/ocre/ocre_timers/ocre_timer.c b/src/ocre/ocre_timers/ocre_timer.c index d53e145e..ca9a122b 100644 --- a/src/ocre/ocre_timers/ocre_timer.c +++ b/src/ocre/ocre_timers/ocre_timer.c @@ -10,17 +10,26 @@ #include #include +#include +#include +#include +#include + +#ifdef CONFIG_ZEPHYR #include #include #include - LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); +#else +#include +#include +#include +#include +#endif -#include -#include -#include - -// Compact timer structure +/* Platform-specific timer structures */ +#ifdef CONFIG_ZEPHYR +// Compact timer structure for Zephyr typedef struct { uint32_t in_use: 1; uint32_t id: 8; // Up to 256 timers @@ -30,6 +39,23 @@ typedef struct { wasm_module_inst_t owner; } ocre_timer; +#else /* POSIX */ +// POSIX timer structure +typedef struct { + uint32_t in_use: 1; + uint32_t id: 8; // Up to 256 timers + uint32_t interval: 16; // Up to 65s intervals + uint32_t periodic: 1; + timer_t timer; + pthread_t thread; + bool thread_running; + wasm_module_inst_t owner; +} ocre_timer; + +/* POSIX timer thread function */ +static void* posix_timer_thread(void* arg); +#endif + #ifndef CONFIG_MAX_TIMER #define CONFIG_MAX_TIMERS 5 #endif @@ -38,7 +64,12 @@ typedef struct { static ocre_timer timers[CONFIG_MAX_TIMERS]; static bool timer_system_initialized = false; +#ifdef CONFIG_ZEPHYR static void timer_callback_wrapper(struct k_timer *timer); +#else +static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc); +static void posix_send_timer_event(int timer_id); +#endif void ocre_timer_init(void) { if (timer_system_initialized) { @@ -51,6 +82,18 @@ void ocre_timer_init(void) { return; } +#ifndef CONFIG_ZEPHYR + // Setup POSIX signal handler for timer callbacks + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = posix_timer_signal_handler; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) == -1) { + LOG_ERR("Failed to setup POSIX timer signal handler"); + return; + } +#endif + ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_TIMER, ocre_timer_cleanup_container); timer_system_initialized = true; LOG_INF("Timer system initialized"); @@ -72,7 +115,24 @@ int ocre_timer_create(wasm_exec_env_t exec_env, int id) { timer->id = id; timer->owner = module; timer->in_use = 1; + +#ifdef CONFIG_ZEPHYR k_timer_init(&timer->timer, timer_callback_wrapper, NULL); +#else + struct sigevent sev; + memset(&sev, 0, sizeof(sev)); + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIGALRM; + sev.sigev_value.sival_int = id; + + if (timer_create(CLOCK_REALTIME, &sev, &timer->timer) == -1) { + LOG_ERR("Failed to create POSIX timer %d", id); + timer->in_use = 0; + return -EINVAL; + } + timer->thread_running = false; +#endif + ocre_increment_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); LOG_INF("Created timer %d for module %p", id, (void *)module); return 0; @@ -90,7 +150,17 @@ int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id) { LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); return -EINVAL; } + +#ifdef CONFIG_ZEPHYR k_timer_stop(&timer->timer); +#else + timer_delete(&timer->timer); + if (timer->thread_running) { + pthread_cancel(timer->thread); + timer->thread_running = false; + } +#endif + timer->in_use = 0; timer->owner = NULL; ocre_decrement_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); @@ -118,9 +188,30 @@ int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, in timer->interval = interval; timer->periodic = is_periodic; + +#ifdef CONFIG_ZEPHYR k_timeout_t duration = K_MSEC(interval); k_timeout_t period = is_periodic ? duration : K_NO_WAIT; k_timer_start(&timer->timer, duration, period); +#else + struct itimerspec its; + its.it_value.tv_sec = interval / 1000; + its.it_value.tv_nsec = (interval % 1000) * 1000000; + + if (is_periodic) { + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + } else { + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + } + + if (timer_settime(timer->timer, 0, &its, NULL) == -1) { + LOG_ERR("Failed to start POSIX timer %d", id); + return -EINVAL; + } +#endif + LOG_INF("Started timer %d with interval %dms, periodic=%d", id, interval, is_periodic); return 0; } @@ -137,7 +228,15 @@ int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id) { LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); return -EINVAL; } + +#ifdef CONFIG_ZEPHYR k_timer_stop(&timer->timer); +#else + struct itimerspec its; + memset(&its, 0, sizeof(its)); + timer_settime(timer->timer, 0, &its, NULL); +#endif + LOG_INF("Stopped timer %d", id); return 0; } @@ -154,7 +253,19 @@ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id) { LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); return -EINVAL; } - int remaining = k_ticks_to_ms_floor32(k_timer_remaining_ticks(&timer->timer)); + + int remaining; +#ifdef CONFIG_ZEPHYR + remaining = k_ticks_to_ms_floor32(k_timer_remaining_ticks(&timer->timer)); +#else + struct itimerspec its; + if (timer_gettime(timer->timer, &its) == -1) { + LOG_ERR("Failed to get remaining time for timer %d", id); + return -EINVAL; + } + remaining = its.it_value.tv_sec * 1000 + its.it_value.tv_nsec / 1000000; +#endif + LOG_INF("Timer %d remaining time: %dms", id, remaining); return remaining; } @@ -167,7 +278,15 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { if (timers[i].in_use && timers[i].owner == module_inst) { +#ifdef CONFIG_ZEPHYR k_timer_stop(&timers[i].timer); +#else + timer_delete(&timers[i].timer); + if (timers[i].thread_running) { + pthread_cancel(timers[i].thread); + timers[i].thread_running = false; + } +#endif timers[i].in_use = 0; timers[i].owner = NULL; ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_TIMER); @@ -177,6 +296,7 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { LOG_INF("Cleaned up timer resources for module %p", (void *)module_inst); } +#ifdef CONFIG_ZEPHYR static void timer_callback_wrapper(struct k_timer *timer) { if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); @@ -212,3 +332,47 @@ static void timer_callback_wrapper(struct k_timer *timer) { } } } + +#else /* POSIX */ + +static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc) { + (void)sig; + (void)uc; + if (si && si->si_value.sival_int > 0 && si->si_value.sival_int <= CONFIG_MAX_TIMERS) { + posix_send_timer_event(si->si_value.sival_int); + } +} + +static void posix_send_timer_event(int timer_id) { + if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { + LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); + return; + } + + int index = timer_id - 1; + if (index < 0 || index >= CONFIG_MAX_TIMERS || !timers[index].in_use) { + LOG_ERR("Invalid timer ID %d in callback", timer_id); + return; + } + + ocre_event_t event; + event.type = OCRE_RESOURCE_TYPE_TIMER; + event.data.timer_event.timer_id = timer_id; + event.owner = timers[index].owner; + + LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer_id, (void *)timers[index].owner); + + // Use the POSIX message queue implementation + extern posix_msgq_t ocre_event_queue; + extern posix_spinlock_t ocre_event_queue_lock; + + posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); + if (posix_msgq_put(&ocre_event_queue, &event) != 0) { + LOG_ERR("Failed to queue timer event for timer %d", timer_id); + } else { + LOG_DBG("Queued timer event for timer %d", timer_id); + } + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); +} + +#endif diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index 2a4387ed..4882ddc2 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -21,6 +21,7 @@ #define CONFIG_OCRE_NETWORKING /*!< Enable networking support */ #define CONFIG_OCRE_CONTAINER_FILESYSTEM #define CONFIG_OCRE_CONTAINER_WAMR_TERMINATION +#define CONFIG_OCRE_TIMER // Base paths for the application #define OCRE_BASE_PATH "./ocre_data" /*!< Base directory for Ocre resources */ diff --git a/src/shared/platform/posix/ocre_internal.cmake b/src/shared/platform/posix/ocre_internal.cmake index fa6cfac7..41ed1fb2 100644 --- a/src/shared/platform/posix/ocre_internal.cmake +++ b/src/shared/platform/posix/ocre_internal.cmake @@ -79,6 +79,9 @@ set(lib_sources ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_timer.c # APIs ${OCRE_ROOT_DIR}/src/ocre/api/ocre_api.c + ${OCRE_ROOT_DIR}/src/ocre/api/ocre_common.c + # Timer functionality is now integrated into ocre_common.c + # ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c # Utils ${OCRE_ROOT_DIR}/src/ocre/utils/strlcat.c ) diff --git a/src/shared/platform/zephyr/ocre_internal.cmake b/src/shared/platform/zephyr/ocre_internal.cmake index f79bdff7..4fa0669d 100644 --- a/src/shared/platform/zephyr/ocre_internal.cmake +++ b/src/shared/platform/zephyr/ocre_internal.cmake @@ -88,9 +88,10 @@ set(lib_sources ) # Conditionally add sources -if(CONFIG_OCRE_TIMER) - list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c) -endif() +# Timer functionality is now integrated into ocre_common.c +# if(CONFIG_OCRE_TIMER) +# list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c) +# endif() if(CONFIG_OCRE_SENSORS) list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_sensors/ocre_sensors.c) From 8cd1c287a1f503d27246bfc866127f762e6b9314 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 09:09:42 +0200 Subject: [PATCH 02/26] Messaging works Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_api.c | 3 +- src/ocre/api/ocre_common.c | 312 ++++++++++++++++++ src/ocre/api/ocre_common.h | 51 ++- .../container_supervisor/cs_sm_impl.c | 3 +- .../container_messaging_posix/messaging.c | 280 ---------------- .../container_messaging_posix/messaging.h | 56 ---- src/shared/platform/posix/core_internal.h | 2 +- .../platform/zephyr/ocre_internal.cmake | 3 +- 8 files changed, 369 insertions(+), 341 deletions(-) delete mode 100644 src/ocre/container_messaging_posix/messaging.c delete mode 100644 src/ocre/container_messaging_posix/messaging.h diff --git a/src/ocre/api/ocre_api.c b/src/ocre/api/ocre_api.c index f9f9d8db..b64a838e 100644 --- a/src/ocre/api/ocre_api.c +++ b/src/ocre/api/ocre_api.c @@ -40,7 +40,8 @@ #endif #ifdef CONFIG_OCRE_CONTAINER_MESSAGING -#include "../ocre_messaging/ocre_messaging.h" +/* Messaging functionality is now integrated into ocre_common.c */ +/* #include "../ocre_messaging/ocre_messaging.h" */ #endif int _ocre_posix_uname(wasm_exec_env_t exec_env, struct _ocre_posix_utsname *name) { diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index d8f1b05e..9bf9378c 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -454,6 +454,9 @@ int ocre_common_init(void) { /* Initialize timer system as part of common initialization */ ocre_timer_init(); + /* Initialize messaging system as part of common initialization */ + ocre_messaging_init(); + LOG_INF("OCRE common initialized successfully"); return 0; } @@ -1050,3 +1053,312 @@ static void posix_send_timer_event(int timer_id) { } #endif + +/* ========== OCRE MESSAGING FUNCTIONALITY ========== */ + +#define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 32 +#define OCRE_MAX_TOPIC_LEN 64 + +/* Messaging subscription structure */ +typedef struct { + char topic[OCRE_MAX_TOPIC_LEN]; + wasm_module_inst_t module_inst; + bool is_active; +} ocre_messaging_subscription_t; + +typedef struct { + ocre_messaging_subscription_t subscriptions[CONFIG_MESSAGING_MAX_SUBSCRIPTIONS]; + uint16_t subscription_count; +#ifdef CONFIG_ZEPHYR + struct k_mutex mutex; +#else + pthread_mutex_t mutex; +#endif +} ocre_messaging_system_t; + +static ocre_messaging_system_t messaging_system = {0}; +static bool messaging_system_initialized = false; + +/* Initialize messaging system */ +int ocre_messaging_init(void) { + if (messaging_system_initialized) { + LOG_INF("Messaging system already initialized"); + return 0; + } + + memset(&messaging_system, 0, sizeof(ocre_messaging_system_t)); + +#ifdef CONFIG_ZEPHYR + k_mutex_init(&messaging_system.mutex); +#else + pthread_mutex_init(&messaging_system.mutex, NULL); +#endif + + ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_MESSAGING, ocre_messaging_cleanup_container); + messaging_system_initialized = true; + LOG_INF("Messaging system initialized"); + return 0; +} + +/* Cleanup messaging resources for a module */ +void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { + if (!messaging_system_initialized || !module_inst) { + return; + } + +#ifdef CONFIG_ZEPHYR + k_mutex_lock(&messaging_system.mutex, K_FOREVER); +#else + OCRE_MUTEX_LOCK(&messaging_system.mutex); +#endif + + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (messaging_system.subscriptions[i].is_active && + messaging_system.subscriptions[i].module_inst == module_inst) { + messaging_system.subscriptions[i].is_active = false; + messaging_system.subscriptions[i].module_inst = NULL; + messaging_system.subscriptions[i].topic[0] = '\0'; + messaging_system.subscription_count--; + ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); + LOG_INF("Cleaned up subscription %d for module %p", i, (void *)module_inst); + } + } + +#ifdef CONFIG_ZEPHYR + k_mutex_unlock(&messaging_system.mutex); +#else + OCRE_MUTEX_UNLOCK(&messaging_system.mutex); +#endif + + LOG_INF("Cleaned up messaging resources for module %p", (void *)module_inst); +} + +/* Subscribe to a topic */ +int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { + if (!messaging_system_initialized) { + if (ocre_messaging_init() != 0) { + LOG_ERR("Failed to initialize messaging system"); + return -EINVAL; + } + } + + if (!topic || ((char *)topic)[0] == '\0') { + LOG_ERR("Topic is NULL or empty"); + return -EINVAL; + } + + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + if (!module_inst) { + LOG_ERR("No module instance for exec_env"); + return -EINVAL; + } + + ocre_module_context_t *ctx = ocre_get_module_context(module_inst); + if (!ctx) { + LOG_ERR("Module context not found for module instance %p", (void *)module_inst); + return -EINVAL; + } + +#ifdef CONFIG_ZEPHYR + k_mutex_lock(&messaging_system.mutex, K_FOREVER); +#else + OCRE_MUTEX_LOCK(&messaging_system.mutex); +#endif + + // Check if already subscribed + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (messaging_system.subscriptions[i].is_active && + messaging_system.subscriptions[i].module_inst == module_inst && + strcmp(messaging_system.subscriptions[i].topic, (char *)topic) == 0) { + LOG_INF("Already subscribed to topic: %s", (char *)topic); +#ifdef CONFIG_ZEPHYR + k_mutex_unlock(&messaging_system.mutex); +#else + OCRE_MUTEX_UNLOCK(&messaging_system.mutex); +#endif + return 0; + } + } + + // Find a free slot + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (!messaging_system.subscriptions[i].is_active) { + strncpy(messaging_system.subscriptions[i].topic, (char *)topic, OCRE_MAX_TOPIC_LEN - 1); + messaging_system.subscriptions[i].topic[OCRE_MAX_TOPIC_LEN - 1] = '\0'; + messaging_system.subscriptions[i].module_inst = module_inst; + messaging_system.subscriptions[i].is_active = true; + messaging_system.subscription_count++; + ocre_increment_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); + LOG_INF("Subscribed to topic: %s, module: %p", (char *)topic, (void *)module_inst); +#ifdef CONFIG_ZEPHYR + k_mutex_unlock(&messaging_system.mutex); +#else + OCRE_MUTEX_UNLOCK(&messaging_system.mutex); +#endif + return 0; + } + } + +#ifdef CONFIG_ZEPHYR + k_mutex_unlock(&messaging_system.mutex); +#else + OCRE_MUTEX_UNLOCK(&messaging_system.mutex); +#endif + + LOG_ERR("No free subscription slots available"); + return -ENOMEM; +} + +/* Publish a message */ +int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len) { + if (!messaging_system_initialized) { + if (ocre_messaging_init() != 0) { + LOG_ERR("Failed to initialize messaging system"); + return -EINVAL; + } + } + + if (!topic || ((char *)topic)[0] == '\0') { + LOG_ERR("Topic is NULL or empty"); + return -EINVAL; + } + if (!content_type || ((char *)content_type)[0] == '\0') { + LOG_ERR("Content type is NULL or empty"); + return -EINVAL; + } + if (!payload || payload_len <= 0) { + LOG_ERR("Payload is NULL or payload_len is invalid"); + return -EINVAL; + } + + wasm_module_inst_t publisher_module = wasm_runtime_get_module_inst(exec_env); + if (!publisher_module) { + LOG_ERR("No module instance for exec_env"); + return -EINVAL; + } + + static uint32_t message_id = 0; + bool message_sent = false; + +#ifdef CONFIG_ZEPHYR + k_mutex_lock(&messaging_system.mutex, K_FOREVER); +#else + OCRE_MUTEX_LOCK(&messaging_system.mutex); +#endif + + // Find matching subscriptions + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (!messaging_system.subscriptions[i].is_active) { + continue; + } + + // Check if the published topic matches the subscription (prefix match) + const char *subscribed_topic = messaging_system.subscriptions[i].topic; + size_t subscribed_len = strlen(subscribed_topic); + + if (strncmp(subscribed_topic, (char *)topic, subscribed_len) != 0) { + continue; // No prefix match + } + + wasm_module_inst_t target_module = messaging_system.subscriptions[i].module_inst; + if (!target_module) { + LOG_ERR("Invalid module instance for subscription %d", i); + continue; + } + + // Allocate WASM memory for the target module + uint32_t topic_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)topic, strlen((char *)topic) + 1); + if (topic_offset == 0) { + LOG_ERR("Failed to allocate WASM memory for topic"); + continue; + } + + uint32_t content_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)content_type, strlen((char *)content_type) + 1); + if (content_offset == 0) { + LOG_ERR("Failed to allocate WASM memory for content_type"); + wasm_runtime_module_free(target_module, topic_offset); + continue; + } + + uint32_t payload_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, payload, payload_len); + if (payload_offset == 0) { + LOG_ERR("Failed to allocate WASM memory for payload"); + wasm_runtime_module_free(target_module, topic_offset); + wasm_runtime_module_free(target_module, content_offset); + continue; + } + + // Create and queue the messaging event + ocre_event_t event; + event.type = OCRE_RESOURCE_TYPE_MESSAGING; + event.data.messaging_event.message_id = message_id; + event.data.messaging_event.topic = topic; + event.data.messaging_event.topic_offset = topic_offset; + event.data.messaging_event.content_type = content_type; + event.data.messaging_event.content_type_offset = content_offset; + event.data.messaging_event.payload = payload; + event.data.messaging_event.payload_offset = payload_offset; + event.data.messaging_event.payload_len = (uint32_t)payload_len; + event.owner = target_module; + + LOG_DBG("Creating messaging event: ID=%d, topic=%s, content_type=%s, payload_len=%d for module %p", + message_id, (char *)topic, (char *)content_type, payload_len, (void *)target_module); + +#ifdef CONFIG_ZEPHYR + k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); + if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { + LOG_ERR("Failed to queue messaging event for message ID %d", message_id); + wasm_runtime_module_free(target_module, topic_offset); + wasm_runtime_module_free(target_module, content_offset); + wasm_runtime_module_free(target_module, payload_offset); + } else { + message_sent = true; + LOG_DBG("Queued messaging event for message ID %d", message_id); + } + k_spin_unlock(&ocre_event_queue_lock, key); +#else + posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); + if (posix_msgq_put(&ocre_event_queue, &event) != 0) { + LOG_ERR("Failed to queue messaging event for message ID %d", message_id); + wasm_runtime_module_free(target_module, topic_offset); + wasm_runtime_module_free(target_module, content_offset); + wasm_runtime_module_free(target_module, payload_offset); + } else { + message_sent = true; + LOG_DBG("Queued messaging event for message ID %d", message_id); + } + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); +#endif + } + +#ifdef CONFIG_ZEPHYR + k_mutex_unlock(&messaging_system.mutex); +#else + OCRE_MUTEX_UNLOCK(&messaging_system.mutex); +#endif + + if (message_sent) { + LOG_DBG("Published message: ID=%d, topic=%s, content_type=%s, payload_len=%d", + message_id, (char *)topic, (char *)content_type, payload_len); + message_id++; + return 0; + } else { + LOG_ERR("No matching subscriptions found for topic %s", (char *)topic); + return -ENOENT; + } +} + +/* Free module event data */ +int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, uint32_t payload_offset) { + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + if (!module_inst) { + LOG_ERR("Cannot find module_inst for free event data"); + return -EINVAL; + } + + wasm_runtime_module_free(module_inst, topic_offset); + wasm_runtime_module_free(module_inst, content_offset); + wasm_runtime_module_free(module_inst, payload_offset); + + return 0; +} diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index 1c462770..97d68c94 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -16,7 +16,8 @@ #ifdef CONFIG_ZEPHYR #include #include -#include "../ocre_messaging/ocre_messaging.h" +/* Messaging functionality is now integrated into ocre_common.c */ +/* #include "../ocre_messaging/ocre_messaging.h" */ #else #include /* Forward declarations for POSIX messaging types */ @@ -283,4 +284,52 @@ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id); */ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst); +/* ========== OCRE MESSAGING FUNCTIONALITY ========== */ + +/** + * @brief Initialize the messaging system. + * + * @return 0 on success, negative error code on failure. + */ +int ocre_messaging_init(void); + +/** + * @brief Subscribe to a topic. + * + * @param exec_env WASM execution environment. + * @param topic Topic to subscribe to. + * @return 0 on success, negative error code on failure. + */ +int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic); + +/** + * @brief Publish a message to a topic. + * + * @param exec_env WASM execution environment. + * @param topic Topic to publish to. + * @param content_type Content type of the message. + * @param payload Message payload. + * @param payload_len Length of the payload. + * @return 0 on success, negative error code on failure. + */ +int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len); + +/** + * @brief Free module event data. + * + * @param exec_env WASM execution environment. + * @param topic_offset Topic offset in WASM memory. + * @param content_offset Content type offset in WASM memory. + * @param payload_offset Payload offset in WASM memory. + * @return 0 on success, negative error code on failure. + */ +int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, uint32_t payload_offset); + +/** + * @brief Cleanup messaging resources for a module. + * + * @param module_inst WASM module instance. + */ +void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst); + #endif /* OCRE_COMMON_H */ diff --git a/src/ocre/components/container_supervisor/cs_sm_impl.c b/src/ocre/components/container_supervisor/cs_sm_impl.c index 9ba3aafa..fa7f4a66 100644 --- a/src/ocre/components/container_supervisor/cs_sm_impl.c +++ b/src/ocre/components/container_supervisor/cs_sm_impl.c @@ -15,7 +15,8 @@ #include "ocre_gpio/ocre_gpio.h" #endif #ifdef CONFIG_OCRE_CONTAINER_MESSAGING -#include "ocre_messaging/ocre_messaging.h" +/* Messaging functionality is now integrated into ocre_common.c */ +/* #include "ocre_messaging/ocre_messaging.h" */ #endif #if defined(CONFIG_OCRE_TIMER) || defined(CONFIG_OCRE_GPIO) || defined(CONFIG_OCRE_SENSORS) || \ defined(CONFIG_OCRE_CONTAINER_MESSAGING) diff --git a/src/ocre/container_messaging_posix/messaging.c b/src/ocre/container_messaging_posix/messaging.c deleted file mode 100644 index c3d0ba24..00000000 --- a/src/ocre/container_messaging_posix/messaging.c +++ /dev/null @@ -1,280 +0,0 @@ -/** - * @copyright Copyright © contributors to Project Ocre, - * which has been established as Project Ocre a Series of LF Projects, LLC - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include "messaging.h" -#include "ocre/utils/utils.h" - -#define MAX_MSG_SIZE 4096 - -#include -#include -#include -#include -#include -#include -#include -#include - -#define QUEUE_SIZE 10 -#define STACK_SIZE 1024 -#define PRIORITY 5 -#define WASM_STACK_SIZE (8 * 1024) - -static mqd_t ocre_msg_queue; -char mq_name[32]; -static pthread_t subscriber_thread_data; -static struct mq_attr mq_attr = { - .mq_flags = 0, - .mq_maxmsg = QUEUE_SIZE, - .mq_msgsize = MAX_MSG_SIZE, - .mq_curmsgs = 0 -}; - -#define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 10 - -void cleanup_messaging() { - mq_close(ocre_msg_queue); - mq_unlink(mq_name); - exit(0); // Terminate the process after cleanup -} - - -// Structure to hold the subscription information -typedef struct { - char *topic; - wasm_function_inst_t handler; - wasm_module_inst_t module_inst; -} ocre_subscription_t; - -static ocre_subscription_t subscriptions[CONFIG_MESSAGING_MAX_SUBSCRIPTIONS]; -static int subscription_count = 0; -static bool msg_system_is_init = false; - -static uint32_t allocate_wasm_memory(wasm_module_inst_t module_inst, const void *src, size_t size) { - void *native_addr = NULL; - uint64_t wasm_ptr = wasm_runtime_module_malloc(module_inst, size, &native_addr); - if (!wasm_ptr || !native_addr) { - LOG_ERR("Failed to allocate memory in WASM"); - return 0; - } - if (src) { - memcpy(native_addr, src, size); - } - return (uint32_t)wasm_ptr; -} - -static void free_wasm_message(wasm_module_inst_t module_inst, uint32_t *ptr_array, uint16_t count) { - for (uint16_t i = 0; i < count; i++) { - if (ptr_array[i]) { - wasm_runtime_module_free(module_inst, ptr_array[i]); - } - } -} - -void* subscriber_thread(void *arg) { - wasm_runtime_init_thread_env(); - uint8_t buffer[MAX_MSG_SIZE]; - while (1) { - ssize_t msg_size = mq_receive(ocre_msg_queue, (char *)buffer, sizeof(buffer), NULL); - if (msg_size >= (ssize_t)sizeof(ocre_msg_t)) { - LOG_INF("Got a message from another container"); - ocre_msg_t *msg = (ocre_msg_t *)buffer; - char *topic = (char *)(buffer + msg->topic); - char *content_type = (char *)(buffer + msg->content_type); - void *payload = (void *)(buffer + msg->payload); - - for (int i = 0; i < subscription_count; i++) { - if (strcmp(subscriptions[i].topic, topic) == 0) { - wasm_module_inst_t module_inst = subscriptions[i].module_inst; - if (!module_inst) { - LOG_ERR("Invalid module instance"); - continue; - } - - // Create exec_env for this thread/call - wasm_exec_env_t exec_env = wasm_runtime_create_exec_env(module_inst, WASM_STACK_SIZE); - if (!exec_env) { - LOG_ERR("Failed to create exec_env"); - continue; - } - - uint32_t topic_offset = - (uint32_t)wasm_runtime_module_dup_data(module_inst, topic, strlen(topic) + 1); - if (topic_offset == 0) { - LOG_ERR("Failed to allocate memory for topic in WASM"); - continue; - } - uint32_t content_offset = (uint32_t)wasm_runtime_module_dup_data(module_inst, content_type, strlen(content_type) + 1); - if (content_offset == 0) { - LOG_ERR("Failed to allocate memory for content_type in WASM"); - wasm_runtime_module_free(module_inst, topic_offset); - continue; - } - uint32_t payload_offset = - (uint32_t)wasm_runtime_module_dup_data(module_inst, payload, msg->payload_len); - if (payload_offset == 0) { - LOG_ERR("Failed to allocate memory for payload in WASM"); - wasm_runtime_module_free(module_inst, topic_offset); - wasm_runtime_module_free(module_inst, content_offset); - continue; - } - - uint32_t args[5] = {msg->mid, topic_offset, content_offset, payload_offset, msg->payload_len}; - if (!wasm_runtime_call_wasm(exec_env, subscriptions[i].handler, 5, args)) { - const char *error = wasm_runtime_get_exception(module_inst); - LOG_ERR("Failed to call WASM function: %s", error ? error : "Unknown error"); - } else { - LOG_INF("Function executed successfully"); - } - - // Free memory and exec_env - wasm_runtime_module_free(module_inst, topic_offset); - wasm_runtime_module_free(module_inst, content_offset); - wasm_runtime_module_free(module_inst, payload_offset); - wasm_runtime_destroy_exec_env(exec_env); - } - } - } else { - core_sleep_ms(1000); - } - } - printf("do I get here?\n"); - wasm_runtime_destroy_thread_env(); - return NULL; -} - -void ocre_msg_system_init() { - if (msg_system_is_init) { - LOG_WRN("Messaging System is already initialized"); - return; - } - - // POSIX: Create message queue and thread - snprintf(mq_name, sizeof(mq_name), "/ocre_msgq_%d", getpid()); - ocre_msg_queue = mq_open(mq_name, O_CREAT | O_RDWR, 0644, &mq_attr); - if (ocre_msg_queue == (mqd_t)-1) { - perror("Failed to create message queue"); - return; - } - if (pthread_create(&subscriber_thread_data, NULL, subscriber_thread, NULL) != 0) { - perror("Failed to create subscriber thread"); - mq_close(ocre_msg_queue); - mq_unlink(mq_name); // Clean up if thread creation fails - return; - } - msg_system_is_init = true; -} - -int ocre_publish_message(wasm_exec_env_t exec_env, char *topic, char *content_type, void *payload, int payload_len) { - LOG_INF("---------------_ocre_publish_message: topic: %s [%zu], content_type: %s, payload_len: %u ", topic, - strlen(topic), content_type, payload_len); - - if (!msg_system_is_init) { - LOG_ERR("Messaging system not initialized"); - return -1; - } - - if (!topic || (topic[0] == '\0')) { - LOG_ERR("topic is NULL or empty, please check function parameters!"); - return -1; - } - - if (!content_type || (content_type[0] == '\0')) { - LOG_ERR("content_type is NULL or empty, please check function parameters!"); - return -1; - } - - if (!payload || payload_len == 0) { - LOG_ERR("payload is NULL or payload_len is 0, please check function parameters!"); - return -1; - } - - static uint64_t message_id = 0; - - size_t topic_len = strlen(topic) + 1; - size_t content_type_len = strlen(content_type) + 1; - size_t total_size = sizeof(ocre_msg_t) + topic_len + content_type_len + payload_len; - - if (total_size > MAX_MSG_SIZE) { - LOG_ERR("Message too large for queue: %zu > %d", total_size, MAX_MSG_SIZE); - return -1; - } - - uint8_t *buffer = malloc(total_size); - if (!buffer) { - LOG_ERR("Failed to allocate message buffer"); - return -1; - } - - ocre_msg_t *msg = (ocre_msg_t *)buffer; - msg->mid = message_id++; - msg->topic = sizeof(ocre_msg_t); - msg->content_type = msg->topic + topic_len; - msg->payload = msg->content_type + content_type_len; - msg->payload_len = payload_len; - - memcpy(buffer + msg->topic, topic, topic_len); - memcpy(buffer + msg->content_type, content_type, content_type_len); - memcpy(buffer + msg->payload, payload, payload_len); - - if (mq_send(ocre_msg_queue, (const char *)buffer, total_size, 0) != 0) { - perror("Message queue is full or error occurred"); - free(buffer); - return -1; - } - free(buffer); - - return 0; -} - -int ocre_subscribe_message(wasm_exec_env_t exec_env, char *topic, char *handler_name) { - LOG_INF("---------------_ocre_subscribe_message---------------"); - - if (!msg_system_is_init) { - LOG_ERR("Messaging system not initialized"); - return -1; - } - - signal(SIGINT, cleanup_messaging); - signal(SIGTERM, cleanup_messaging); - - if (subscription_count < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS) { - - if (!topic || (topic[0] == '\0')) { - LOG_ERR("topic is NULL or empty, please check function parameters!"); - return -1; - } - - if (!handler_name || (handler_name[0] == '\0')) { - LOG_ERR("handler_name is NULL or empty, please check function parameters!"); - return -1; - } - - wasm_module_inst_t current_module_inst = wasm_runtime_get_module_inst(exec_env); - wasm_function_inst_t handler_function = wasm_runtime_lookup_function(current_module_inst, handler_name); - if (!handler_function) { - LOG_ERR("Failed to find %s in WASM module", handler_name); - return -1; - } - - subscriptions[subscription_count].topic = topic; - subscriptions[subscription_count].handler = handler_function; - subscriptions[subscription_count].module_inst = current_module_inst; - - LOG_INF("WASM messaging callback function set successfully"); - - subscription_count++; - } else { - LOG_ERR("Maximum subscriptions reached, could not subscribe to topic"); - return -1; - } - - return 0; -} diff --git a/src/ocre/container_messaging_posix/messaging.h b/src/ocre/container_messaging_posix/messaging.h deleted file mode 100644 index 2bf77b2c..00000000 --- a/src/ocre/container_messaging_posix/messaging.h +++ /dev/null @@ -1,56 +0,0 @@ - -/** - * @copyright Copyright © contributors to Project Ocre, - * which has been established as Project Ocre a Series of LF Projects, LLC - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CONTAINER_MESSAGING_POSIX_H -#define CONTAINER_MESSAGING_POSIX_H -#include "wasm_export.h" - -/** - * @typedef ocre_msg - * - * Structure of ocre messages - * - */ -typedef struct ocre_msg { - // message id - increments on each message - uint64_t mid; - // url of the request - uint32_t topic; // offset from start of buffer - // payload format (MIME type??) - uint32_t content_type; // offset from start of buffer - // payload of the request - uint32_t payload; // offset from start of buffer - // length in bytes of the payload - int32_t payload_len; -} ocre_msg_t; - -/** - * @brief Initialize OCRE Messaging System. - * - */ -void ocre_msg_system_init(); - -/** - * @brief Publish a message to the specified target. - * - * @param topic the name of the topic on which to publish the message - * @param content_type the content type of the message; it is recommended to use a MIME type - * @param payload a buffer containing the message contents - * @param payload_len the length of the payload buffer - */ -int ocre_publish_message(wasm_exec_env_t exec_env, char *topic, char *content_type, void *payload, int payload_len); - -/** - * @brief Subscribe to messages on the specified topic. - * - * @param topic the name of the topic on which to subscribe - * @param handler_name name of callback function that will be called when a message is received on this topic - */ -int ocre_subscribe_message(wasm_exec_env_t exec_env, char *topic, char *handler_name); - -#endif /* CONTAINER_MESSAGING_POSIX_H */ diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index 4882ddc2..c996920f 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -17,7 +17,7 @@ #include // Config macros -//#define CONFIG_OCRE_CONTAINER_MESSAGING /*!< Enable container messaging support */ +#define CONFIG_OCRE_CONTAINER_MESSAGING /*!< Enable container messaging support */ #define CONFIG_OCRE_NETWORKING /*!< Enable networking support */ #define CONFIG_OCRE_CONTAINER_FILESYSTEM #define CONFIG_OCRE_CONTAINER_WAMR_TERMINATION diff --git a/src/shared/platform/zephyr/ocre_internal.cmake b/src/shared/platform/zephyr/ocre_internal.cmake index 4fa0669d..5e67c1d4 100644 --- a/src/shared/platform/zephyr/ocre_internal.cmake +++ b/src/shared/platform/zephyr/ocre_internal.cmake @@ -106,7 +106,8 @@ if(DEFINED CONFIG_OCRE_GPIO) endif() if(CONFIG_OCRE_CONTAINER_MESSAGING) - list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_messaging/ocre_messaging.c) + # Messaging functionality is now integrated into ocre_common.c + # list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_messaging/ocre_messaging.c) endif() # Add all sources to the app target at once From 9484e486edf7db70230ba6661673b05d3073a5d6 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 09:26:53 +0200 Subject: [PATCH 03/26] Fix Zephyr Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 88 ++++++++++++++++++++------------------ src/ocre/api/ocre_common.h | 4 +- 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 9bf9378c..12ed39b4 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -14,36 +14,38 @@ #include #include -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ #include #include #include #include #include -LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); #include #include +LOG_MODULE_REGISTER(ocre_common, LOG_LEVEL_DBG); #else /* POSIX */ #include #include #include #include #include +#include /* POSIX logging macros are already defined in core_internal.h */ #endif #include "../../../../../wasm-micro-runtime/core/iwasm/include/lib_export.h" #include "bh_log.h" -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ #include "../ocre_gpio/ocre_gpio.h" -#include "../ocre_messaging/ocre_messaging.h" +/* Messaging functionality is now integrated into this file */ +/* #include "../ocre_messaging/ocre_messaging.h" */ #endif #include "ocre_common.h" /* Platform-specific abstractions */ -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ #define SIZE_OCRE_EVENT_BUFFER 32 __attribute__((section(".noinit.ocre_event_queue"), @@ -239,7 +241,7 @@ static int posix_msgq_put(posix_msgq_t *msgq, const ocre_event_t *event) { var; \ var = (module_node_t *)(var->node.next)) -#endif /* CONFIG_ZEPHYR */ +#endif /* __ZEPHYR__ */ static struct cleanup_handler { ocre_resource_type_t type; @@ -297,7 +299,7 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o ocre_event_t event; int ret; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); ret = k_msgq_peek(&ocre_event_queue, &event); if (ret != 0) { @@ -384,7 +386,7 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o ================================= */ default: { -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_spin_unlock(&ocre_event_queue_lock, key); #else OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); @@ -393,7 +395,7 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o return -EINVAL; } } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_spin_unlock(&ocre_event_queue_lock, key); #else OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); @@ -408,7 +410,7 @@ int ocre_common_init(void) { return 0; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_init(®istry_mutex); sys_slist_init(&module_registry); if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { @@ -507,7 +509,7 @@ int ocre_register_module(wasm_module_inst_t module_inst) { memset(node->ctx.resource_count, 0, sizeof(node->ctx.resource_count)); memset(node->ctx.dispatchers, 0, sizeof(node->ctx.dispatchers)); -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(®istry_mutex, K_FOREVER); sys_slist_append(&module_registry, &node->node); k_mutex_unlock(®istry_mutex); @@ -527,7 +529,7 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { return; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(®istry_mutex, K_FOREVER); module_node_t *node, *tmp; SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { @@ -574,7 +576,7 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { int count = 0; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(®istry_mutex, K_FOREVER); for (sys_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); @@ -634,13 +636,13 @@ int ocre_register_dispatcher(wasm_exec_env_t exec_env, ocre_resource_type_t type LOG_ERR("Function %s not found in module %p", function_name, (void *)module_inst); return -EINVAL; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(®istry_mutex, K_FOREVER); #else OCRE_MUTEX_LOCK(®istry_mutex); #endif ctx->dispatchers[type] = func; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(®istry_mutex); #else OCRE_MUTEX_UNLOCK(®istry_mutex); @@ -657,13 +659,13 @@ uint32_t ocre_get_resource_count(wasm_module_inst_t module_inst, ocre_resource_t void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT) { -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(®istry_mutex, K_FOREVER); #else OCRE_MUTEX_LOCK(®istry_mutex); #endif ctx->resource_count[type]++; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(®istry_mutex); #else OCRE_MUTEX_UNLOCK(®istry_mutex); @@ -675,13 +677,13 @@ void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource void ocre_decrement_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT && ctx->resource_count[type] > 0) { -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(®istry_mutex, K_FOREVER); #else OCRE_MUTEX_LOCK(®istry_mutex); #endif ctx->resource_count[type]--; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(®istry_mutex); #else OCRE_MUTEX_UNLOCK(®istry_mutex); @@ -710,7 +712,7 @@ wasm_module_inst_t ocre_get_current_module(void) { typedef uint32_t ocre_timer_t; /* Platform-specific timer structures */ -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ // Compact timer structure for Zephyr typedef struct { uint32_t in_use: 1; @@ -745,7 +747,7 @@ typedef struct { static ocre_timer_internal timers[CONFIG_MAX_TIMERS]; static bool timer_system_initialized = false; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ static void timer_callback_wrapper(struct k_timer *timer); #else static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc); @@ -763,7 +765,7 @@ void ocre_timer_init(void) { return; } -#ifndef CONFIG_ZEPHYR +#ifndef __ZEPHYR__ // Setup POSIX signal handler for timer callbacks struct sigaction sa; sa.sa_flags = SA_SIGINFO; @@ -797,7 +799,7 @@ int ocre_timer_create(wasm_exec_env_t exec_env, int id) { timer->owner = module; timer->in_use = 1; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_init(&timer->timer, timer_callback_wrapper, NULL); #else struct sigevent sev; @@ -832,10 +834,10 @@ int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id) { return -EINVAL; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_stop(&timer->timer); #else - timer_delete(&timer->timer); + timer_delete(timer->timer); if (timer->thread_running) { pthread_cancel(timer->thread); timer->thread_running = false; @@ -870,7 +872,7 @@ int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, in timer->interval = interval; timer->periodic = is_periodic; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timeout_t duration = K_MSEC(interval); k_timeout_t period = is_periodic ? duration : K_NO_WAIT; k_timer_start(&timer->timer, duration, period); @@ -910,7 +912,7 @@ int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id) { return -EINVAL; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_stop(&timer->timer); #else struct itimerspec its; @@ -936,7 +938,7 @@ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id) { } int remaining; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ remaining = k_ticks_to_ms_floor32(k_timer_remaining_ticks(&timer->timer)); #else struct itimerspec its; @@ -959,10 +961,10 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { if (timers[i].in_use && timers[i].owner == module_inst) { -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_stop(&timers[i].timer); #else - timer_delete(&timers[i].timer); + timer_delete(timers[i].timer); if (timers[i].thread_running) { pthread_cancel(timers[i].thread); timers[i].thread_running = false; @@ -977,7 +979,7 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { LOG_INF("Cleaned up timer resources for module %p", (void *)module_inst); } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ static void timer_callback_wrapper(struct k_timer *timer) { if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); @@ -1056,7 +1058,9 @@ static void posix_send_timer_event(int timer_id) { /* ========== OCRE MESSAGING FUNCTIONALITY ========== */ +#ifndef CONFIG_MESSAGING_MAX_SUBSCRIPTIONS #define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 32 +#endif #define OCRE_MAX_TOPIC_LEN 64 /* Messaging subscription structure */ @@ -1069,7 +1073,7 @@ typedef struct { typedef struct { ocre_messaging_subscription_t subscriptions[CONFIG_MESSAGING_MAX_SUBSCRIPTIONS]; uint16_t subscription_count; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ struct k_mutex mutex; #else pthread_mutex_t mutex; @@ -1088,7 +1092,7 @@ int ocre_messaging_init(void) { memset(&messaging_system, 0, sizeof(ocre_messaging_system_t)); -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_init(&messaging_system.mutex); #else pthread_mutex_init(&messaging_system.mutex, NULL); @@ -1106,7 +1110,7 @@ void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { return; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(&messaging_system.mutex, K_FOREVER); #else OCRE_MUTEX_LOCK(&messaging_system.mutex); @@ -1124,7 +1128,7 @@ void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { } } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(&messaging_system.mutex); #else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); @@ -1159,7 +1163,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { return -EINVAL; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(&messaging_system.mutex, K_FOREVER); #else OCRE_MUTEX_LOCK(&messaging_system.mutex); @@ -1171,7 +1175,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { messaging_system.subscriptions[i].module_inst == module_inst && strcmp(messaging_system.subscriptions[i].topic, (char *)topic) == 0) { LOG_INF("Already subscribed to topic: %s", (char *)topic); -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(&messaging_system.mutex); #else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); @@ -1190,7 +1194,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { messaging_system.subscription_count++; ocre_increment_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); LOG_INF("Subscribed to topic: %s, module: %p", (char *)topic, (void *)module_inst); -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(&messaging_system.mutex); #else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); @@ -1199,7 +1203,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { } } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(&messaging_system.mutex); #else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); @@ -1240,7 +1244,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ static uint32_t message_id = 0; bool message_sent = false; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_lock(&messaging_system.mutex, K_FOREVER); #else OCRE_MUTEX_LOCK(&messaging_system.mutex); @@ -1304,7 +1308,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ LOG_DBG("Creating messaging event: ID=%d, topic=%s, content_type=%s, payload_len=%d for module %p", message_id, (char *)topic, (char *)content_type, payload_len, (void *)target_module); -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { LOG_ERR("Failed to queue messaging event for message ID %d", message_id); @@ -1331,7 +1335,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ #endif } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_mutex_unlock(&messaging_system.mutex); #else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index 97d68c94..457ebbbe 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -13,7 +13,7 @@ #include /* Platform-specific includes */ -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ #include #include /* Messaging functionality is now integrated into ocre_common.c */ @@ -35,7 +35,7 @@ extern __thread wasm_module_inst_t *current_module_tls; extern char *ocre_event_queue_buffer_ptr; // Defined in ocre_common.c /* Platform-specific external declarations */ -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ extern struct k_msgq ocre_event_queue; // Defined in ocre_common.c extern struct k_spinlock ocre_event_queue_lock; // Defined in ocre_common.c #else From 77c11cc43c82c880248b8ddd56a946ee7231ae87 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 10:35:32 +0200 Subject: [PATCH 04/26] Commonize some code Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 108 ++++++++----------------------------- 1 file changed, 22 insertions(+), 86 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 12ed39b4..336b2bc7 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -62,15 +62,15 @@ typedef struct module_node { } module_node_t; static sys_slist_t module_registry; -static struct k_mutex registry_mutex; +static core_mutex_t registry_mutex; /* Zephyr-specific macros */ -#define OCRE_MALLOC(size) k_malloc(size) -#define OCRE_FREE(ptr) k_free(ptr) +#define OCRE_MALLOC(size) core_malloc(size) +#define OCRE_FREE(ptr) core_free(ptr) #define OCRE_UPTIME_GET() k_uptime_get_32() -#define OCRE_MUTEX_LOCK(mutex) k_mutex_lock(mutex, K_FOREVER) -#define OCRE_MUTEX_UNLOCK(mutex) k_mutex_unlock(mutex) -#define OCRE_MUTEX_INIT(mutex) k_mutex_init(mutex) +#define OCRE_MUTEX_LOCK(mutex) core_mutex_lock(mutex) +#define OCRE_MUTEX_UNLOCK(mutex) core_mutex_unlock(mutex) +#define OCRE_MUTEX_INIT(mutex) core_mutex_init(mutex) #define OCRE_SPINLOCK_LOCK(lock) k_spin_lock(lock) #define OCRE_SPINLOCK_UNLOCK(lock, key) k_spin_unlock(lock, key) @@ -119,15 +119,15 @@ typedef struct module_node { } module_node_t; static posix_slist_t module_registry; -static pthread_mutex_t registry_mutex; +static core_mutex_t registry_mutex; /* POSIX-specific macros */ -#define OCRE_MALLOC(size) malloc(size) -#define OCRE_FREE(ptr) free(ptr) +#define OCRE_MALLOC(size) core_malloc(size) +#define OCRE_FREE(ptr) core_free(ptr) #define OCRE_UPTIME_GET() posix_uptime_get() -#define OCRE_MUTEX_LOCK(mutex) pthread_mutex_lock(mutex) -#define OCRE_MUTEX_UNLOCK(mutex) pthread_mutex_unlock(mutex) -#define OCRE_MUTEX_INIT(mutex) pthread_mutex_init(mutex, NULL) +#define OCRE_MUTEX_LOCK(mutex) core_mutex_lock(mutex) +#define OCRE_MUTEX_UNLOCK(mutex) core_mutex_unlock(mutex) +#define OCRE_MUTEX_INIT(mutex) core_mutex_init(mutex) #define OCRE_SPINLOCK_LOCK(lock) posix_spinlock_lock(lock) #define OCRE_SPINLOCK_UNLOCK(lock, key) posix_spinlock_unlock(lock, key) @@ -411,7 +411,7 @@ int ocre_common_init(void) { } #ifdef __ZEPHYR__ - k_mutex_init(®istry_mutex); + OCRE_MUTEX_INIT(®istry_mutex); sys_slist_init(&module_registry); if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); @@ -510,9 +510,9 @@ int ocre_register_module(wasm_module_inst_t module_inst) { memset(node->ctx.dispatchers, 0, sizeof(node->ctx.dispatchers)); #ifdef __ZEPHYR__ - k_mutex_lock(®istry_mutex, K_FOREVER); + OCRE_MUTEX_LOCK(®istry_mutex); sys_slist_append(&module_registry, &node->node); - k_mutex_unlock(®istry_mutex); + OCRE_MUTEX_UNLOCK(®istry_mutex); #else OCRE_MUTEX_LOCK(®istry_mutex); posix_slist_append(&module_registry, &node->node); @@ -530,7 +530,7 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { } #ifdef __ZEPHYR__ - k_mutex_lock(®istry_mutex, K_FOREVER); + OCRE_MUTEX_LOCK(®istry_mutex); module_node_t *node, *tmp; SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { if (node->ctx.inst == module_inst) { @@ -544,7 +544,7 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { break; } } - k_mutex_unlock(®istry_mutex); + OCRE_MUTEX_UNLOCK(®istry_mutex); #else OCRE_MUTEX_LOCK(®istry_mutex); module_node_t *node, *tmp; @@ -577,18 +577,18 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { int count = 0; #ifdef __ZEPHYR__ - k_mutex_lock(®istry_mutex, K_FOREVER); + OCRE_MUTEX_LOCK(®istry_mutex); for (sys_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { node->ctx.last_activity = k_uptime_get_32(); - k_mutex_unlock(®istry_mutex); + OCRE_MUTEX_UNLOCK(®istry_mutex); LOG_DBG("Found module context for %p", (void *)module_inst); return &node->ctx; } } - k_mutex_unlock(®istry_mutex); + OCRE_MUTEX_UNLOCK(®istry_mutex); #else OCRE_MUTEX_LOCK(®istry_mutex); for (posix_snode_t *current = module_registry.head; current != NULL; current = current->next) { @@ -636,17 +636,9 @@ int ocre_register_dispatcher(wasm_exec_env_t exec_env, ocre_resource_type_t type LOG_ERR("Function %s not found in module %p", function_name, (void *)module_inst); return -EINVAL; } -#ifdef __ZEPHYR__ - k_mutex_lock(®istry_mutex, K_FOREVER); -#else OCRE_MUTEX_LOCK(®istry_mutex); -#endif ctx->dispatchers[type] = func; -#ifdef __ZEPHYR__ - k_mutex_unlock(®istry_mutex); -#else OCRE_MUTEX_UNLOCK(®istry_mutex); -#endif LOG_INF("Registered dispatcher for type %d: %s", type, function_name); return 0; } @@ -659,17 +651,9 @@ uint32_t ocre_get_resource_count(wasm_module_inst_t module_inst, ocre_resource_t void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT) { -#ifdef __ZEPHYR__ - k_mutex_lock(®istry_mutex, K_FOREVER); -#else OCRE_MUTEX_LOCK(®istry_mutex); -#endif ctx->resource_count[type]++; -#ifdef __ZEPHYR__ - k_mutex_unlock(®istry_mutex); -#else OCRE_MUTEX_UNLOCK(®istry_mutex); -#endif LOG_INF("Incremented resource count: type=%d, count=%d", type, ctx->resource_count[type]); } } @@ -677,17 +661,9 @@ void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource void ocre_decrement_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT && ctx->resource_count[type] > 0) { -#ifdef __ZEPHYR__ - k_mutex_lock(®istry_mutex, K_FOREVER); -#else OCRE_MUTEX_LOCK(®istry_mutex); -#endif ctx->resource_count[type]--; -#ifdef __ZEPHYR__ - k_mutex_unlock(®istry_mutex); -#else OCRE_MUTEX_UNLOCK(®istry_mutex); -#endif LOG_INF("Decremented resource count: type=%d, count=%d", type, ctx->resource_count[type]); } } @@ -1073,11 +1049,7 @@ typedef struct { typedef struct { ocre_messaging_subscription_t subscriptions[CONFIG_MESSAGING_MAX_SUBSCRIPTIONS]; uint16_t subscription_count; -#ifdef __ZEPHYR__ - struct k_mutex mutex; -#else - pthread_mutex_t mutex; -#endif + core_mutex_t mutex; } ocre_messaging_system_t; static ocre_messaging_system_t messaging_system = {0}; @@ -1092,11 +1064,7 @@ int ocre_messaging_init(void) { memset(&messaging_system, 0, sizeof(ocre_messaging_system_t)); -#ifdef __ZEPHYR__ - k_mutex_init(&messaging_system.mutex); -#else - pthread_mutex_init(&messaging_system.mutex, NULL); -#endif + core_mutex_init(&messaging_system.mutex); ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_MESSAGING, ocre_messaging_cleanup_container); messaging_system_initialized = true; @@ -1110,11 +1078,7 @@ void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { return; } -#ifdef __ZEPHYR__ - k_mutex_lock(&messaging_system.mutex, K_FOREVER); -#else OCRE_MUTEX_LOCK(&messaging_system.mutex); -#endif for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { if (messaging_system.subscriptions[i].is_active && @@ -1128,11 +1092,7 @@ void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { } } -#ifdef __ZEPHYR__ - k_mutex_unlock(&messaging_system.mutex); -#else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); -#endif LOG_INF("Cleaned up messaging resources for module %p", (void *)module_inst); } @@ -1163,11 +1123,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { return -EINVAL; } -#ifdef __ZEPHYR__ - k_mutex_lock(&messaging_system.mutex, K_FOREVER); -#else OCRE_MUTEX_LOCK(&messaging_system.mutex); -#endif // Check if already subscribed for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { @@ -1175,11 +1131,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { messaging_system.subscriptions[i].module_inst == module_inst && strcmp(messaging_system.subscriptions[i].topic, (char *)topic) == 0) { LOG_INF("Already subscribed to topic: %s", (char *)topic); -#ifdef __ZEPHYR__ - k_mutex_unlock(&messaging_system.mutex); -#else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); -#endif return 0; } } @@ -1194,20 +1146,12 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { messaging_system.subscription_count++; ocre_increment_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); LOG_INF("Subscribed to topic: %s, module: %p", (char *)topic, (void *)module_inst); -#ifdef __ZEPHYR__ - k_mutex_unlock(&messaging_system.mutex); -#else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); -#endif return 0; } } -#ifdef __ZEPHYR__ - k_mutex_unlock(&messaging_system.mutex); -#else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); -#endif LOG_ERR("No free subscription slots available"); return -ENOMEM; @@ -1244,11 +1188,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ static uint32_t message_id = 0; bool message_sent = false; -#ifdef __ZEPHYR__ - k_mutex_lock(&messaging_system.mutex, K_FOREVER); -#else OCRE_MUTEX_LOCK(&messaging_system.mutex); -#endif // Find matching subscriptions for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { @@ -1335,11 +1275,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ #endif } -#ifdef __ZEPHYR__ - k_mutex_unlock(&messaging_system.mutex); -#else OCRE_MUTEX_UNLOCK(&messaging_system.mutex); -#endif if (message_sent) { LOG_DBG("Published message: ID=%d, topic=%s, content_type=%s, payload_len=%d", From bfe6a29d8af5e0459edd7639d2b520b09a79cda5 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 11:44:22 +0200 Subject: [PATCH 05/26] Remove duplcate macros Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 76 +++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 336b2bc7..58f22f3f 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -65,12 +65,7 @@ static sys_slist_t module_registry; static core_mutex_t registry_mutex; /* Zephyr-specific macros */ -#define OCRE_MALLOC(size) core_malloc(size) -#define OCRE_FREE(ptr) core_free(ptr) #define OCRE_UPTIME_GET() k_uptime_get_32() -#define OCRE_MUTEX_LOCK(mutex) core_mutex_lock(mutex) -#define OCRE_MUTEX_UNLOCK(mutex) core_mutex_unlock(mutex) -#define OCRE_MUTEX_INIT(mutex) core_mutex_init(mutex) #define OCRE_SPINLOCK_LOCK(lock) k_spin_lock(lock) #define OCRE_SPINLOCK_UNLOCK(lock, key) k_spin_unlock(lock, key) @@ -122,12 +117,7 @@ static posix_slist_t module_registry; static core_mutex_t registry_mutex; /* POSIX-specific macros */ -#define OCRE_MALLOC(size) core_malloc(size) -#define OCRE_FREE(ptr) core_free(ptr) #define OCRE_UPTIME_GET() posix_uptime_get() -#define OCRE_MUTEX_LOCK(mutex) core_mutex_lock(mutex) -#define OCRE_MUTEX_UNLOCK(mutex) core_mutex_unlock(mutex) -#define OCRE_MUTEX_INIT(mutex) core_mutex_init(mutex) #define OCRE_SPINLOCK_LOCK(lock) posix_spinlock_lock(lock) #define OCRE_SPINLOCK_UNLOCK(lock, key) posix_spinlock_unlock(lock, key) @@ -411,7 +401,7 @@ int ocre_common_init(void) { } #ifdef __ZEPHYR__ - OCRE_MUTEX_INIT(®istry_mutex); + core_mutex_init(®istry_mutex); sys_slist_init(&module_registry); if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); @@ -423,7 +413,7 @@ int ocre_common_init(void) { LOG_INF("Purged stale event from queue"); } #else /* POSIX */ - OCRE_MUTEX_INIT(®istry_mutex); + core_mutex_init(®istry_mutex); posix_slist_init(&module_registry); if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); @@ -492,7 +482,7 @@ int ocre_register_module(wasm_module_inst_t module_inst) { LOG_ERR("Null module instance"); return -EINVAL; } - module_node_t *node = OCRE_MALLOC(sizeof(module_node_t)); + module_node_t *node = core_malloc(sizeof(module_node_t)); if (!node) { LOG_ERR("Failed to allocate module node"); return -ENOMEM; @@ -501,7 +491,7 @@ int ocre_register_module(wasm_module_inst_t module_inst) { node->ctx.exec_env = wasm_runtime_create_exec_env(module_inst, OCRE_WASM_STACK_SIZE); if (!node->ctx.exec_env) { LOG_ERR("Failed to create exec env for module %p", (void *)module_inst); - OCRE_FREE(node); + core_free(node); return -ENOMEM; } node->ctx.in_use = true; @@ -510,13 +500,13 @@ int ocre_register_module(wasm_module_inst_t module_inst) { memset(node->ctx.dispatchers, 0, sizeof(node->ctx.dispatchers)); #ifdef __ZEPHYR__ - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); sys_slist_append(&module_registry, &node->node); - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); #else - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); posix_slist_append(&module_registry, &node->node); - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); #endif LOG_INF("Module registered: %p", (void *)module_inst); @@ -530,7 +520,7 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { } #ifdef __ZEPHYR__ - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); module_node_t *node, *tmp; SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { if (node->ctx.inst == module_inst) { @@ -544,9 +534,9 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { break; } } - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); #else - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); module_node_t *node, *tmp; module_node_t *prev = NULL; SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { @@ -556,13 +546,13 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { wasm_runtime_destroy_exec_env(node->ctx.exec_env); } posix_slist_remove(&module_registry, prev ? &prev->node : NULL, &node->node); - OCRE_FREE(node); + core_free(node); LOG_INF("Module unregistered: %p", (void *)module_inst); break; } prev = node; } - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); #endif } @@ -577,31 +567,31 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { int count = 0; #ifdef __ZEPHYR__ - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); for (sys_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { node->ctx.last_activity = k_uptime_get_32(); - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); LOG_DBG("Found module context for %p", (void *)module_inst); return &node->ctx; } } - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); #else - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); for (posix_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { node->ctx.last_activity = OCRE_UPTIME_GET(); - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); LOG_DBG("Found module context for %p", (void *)module_inst); return &node->ctx; } } - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); #endif LOG_ERR("Module context not found for %p", (void *)module_inst); @@ -636,9 +626,9 @@ int ocre_register_dispatcher(wasm_exec_env_t exec_env, ocre_resource_type_t type LOG_ERR("Function %s not found in module %p", function_name, (void *)module_inst); return -EINVAL; } - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); ctx->dispatchers[type] = func; - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); LOG_INF("Registered dispatcher for type %d: %s", type, function_name); return 0; } @@ -651,9 +641,9 @@ uint32_t ocre_get_resource_count(wasm_module_inst_t module_inst, ocre_resource_t void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT) { - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); ctx->resource_count[type]++; - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); LOG_INF("Incremented resource count: type=%d, count=%d", type, ctx->resource_count[type]); } } @@ -661,9 +651,9 @@ void ocre_increment_resource_count(wasm_module_inst_t module_inst, ocre_resource void ocre_decrement_resource_count(wasm_module_inst_t module_inst, ocre_resource_type_t type) { ocre_module_context_t *ctx = ocre_get_module_context(module_inst); if (ctx && type < OCRE_RESOURCE_TYPE_COUNT && ctx->resource_count[type] > 0) { - OCRE_MUTEX_LOCK(®istry_mutex); + core_mutex_lock(®istry_mutex); ctx->resource_count[type]--; - OCRE_MUTEX_UNLOCK(®istry_mutex); + core_mutex_unlock(®istry_mutex); LOG_INF("Decremented resource count: type=%d, count=%d", type, ctx->resource_count[type]); } } @@ -1078,7 +1068,7 @@ void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { return; } - OCRE_MUTEX_LOCK(&messaging_system.mutex); + core_mutex_lock(&messaging_system.mutex); for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { if (messaging_system.subscriptions[i].is_active && @@ -1092,7 +1082,7 @@ void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { } } - OCRE_MUTEX_UNLOCK(&messaging_system.mutex); + core_mutex_unlock(&messaging_system.mutex); LOG_INF("Cleaned up messaging resources for module %p", (void *)module_inst); } @@ -1123,7 +1113,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { return -EINVAL; } - OCRE_MUTEX_LOCK(&messaging_system.mutex); + core_mutex_lock(&messaging_system.mutex); // Check if already subscribed for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { @@ -1131,7 +1121,7 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { messaging_system.subscriptions[i].module_inst == module_inst && strcmp(messaging_system.subscriptions[i].topic, (char *)topic) == 0) { LOG_INF("Already subscribed to topic: %s", (char *)topic); - OCRE_MUTEX_UNLOCK(&messaging_system.mutex); + core_mutex_unlock(&messaging_system.mutex); return 0; } } @@ -1146,12 +1136,12 @@ int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { messaging_system.subscription_count++; ocre_increment_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); LOG_INF("Subscribed to topic: %s, module: %p", (char *)topic, (void *)module_inst); - OCRE_MUTEX_UNLOCK(&messaging_system.mutex); + core_mutex_unlock(&messaging_system.mutex); return 0; } } - OCRE_MUTEX_UNLOCK(&messaging_system.mutex); + core_mutex_unlock(&messaging_system.mutex); LOG_ERR("No free subscription slots available"); return -ENOMEM; @@ -1188,7 +1178,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ static uint32_t message_id = 0; bool message_sent = false; - OCRE_MUTEX_LOCK(&messaging_system.mutex); + core_mutex_lock(&messaging_system.mutex); // Find matching subscriptions for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { @@ -1275,7 +1265,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ #endif } - OCRE_MUTEX_UNLOCK(&messaging_system.mutex); + core_mutex_unlock(&messaging_system.mutex); if (message_sent) { LOG_DBG("Published message: ID=%d, topic=%s, content_type=%s, payload_len=%d", From f49e6de2695c018c40330651639108771faee802 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 11:56:48 +0200 Subject: [PATCH 06/26] Create slist module for posix Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 36 ------------------- src/shared/platform/posix/core_internal.h | 15 ++++++++ src/shared/platform/posix/core_slist.c | 27 ++++++++++++++ src/shared/platform/posix/ocre_internal.cmake | 1 + 4 files changed, 43 insertions(+), 36 deletions(-) create mode 100644 src/shared/platform/posix/core_slist.c diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 58f22f3f..b5ee0cdf 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -73,16 +73,6 @@ static core_mutex_t registry_mutex; #define SIZE_OCRE_EVENT_BUFFER 32 -/* POSIX simple linked list implementation */ -typedef struct posix_snode { - struct posix_snode *next; -} posix_snode_t; - -typedef struct { - posix_snode_t *head; - posix_snode_t *tail; -} posix_slist_t; - /* POSIX message queue simulation */ typedef struct { ocre_event_t *buffer; @@ -155,32 +145,6 @@ static void posix_spinlock_unlock(posix_spinlock_t *lock, posix_spinlock_key_t k pthread_mutex_unlock(&lock->mutex); } -static void posix_slist_init(posix_slist_t *list) { - list->head = NULL; - list->tail = NULL; -} - -static void posix_slist_append(posix_slist_t *list, posix_snode_t *node) { - node->next = NULL; - if (list->tail) { - list->tail->next = node; - } else { - list->head = node; - } - list->tail = node; -} - -static void posix_slist_remove(posix_slist_t *list, posix_snode_t *prev, posix_snode_t *node) { - if (prev) { - prev->next = node->next; - } else { - list->head = node->next; - } - if (list->tail == node) { - list->tail = prev; - } -} - static int posix_msgq_init(posix_msgq_t *msgq, size_t item_size, size_t max_items) { msgq->buffer = (ocre_event_t *)ocre_event_queue_buffer; msgq->size = max_items; diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index c996920f..8a9cef65 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -157,4 +157,19 @@ struct core_timer { void *user_data; /*!< User data for the callback */ }; +/* POSIX simple linked list implementation */ +typedef struct posix_snode { + struct posix_snode *next; +} posix_snode_t; + +typedef struct { + posix_snode_t *head; + posix_snode_t *tail; +} posix_slist_t; + +void posix_slist_init(posix_slist_t *list); +void posix_slist_append(posix_slist_t *list, posix_snode_t *node); +void posix_slist_remove(posix_slist_t *list, posix_snode_t *prev, posix_snode_t *node); + + #endif /* OCRE_CORE_INTERNAL_H */ diff --git a/src/shared/platform/posix/core_slist.c b/src/shared/platform/posix/core_slist.c new file mode 100644 index 00000000..023d8566 --- /dev/null +++ b/src/shared/platform/posix/core_slist.c @@ -0,0 +1,27 @@ +#include "ocre_core_external.h" + +void posix_slist_init(posix_slist_t *list) { + list->head = NULL; + list->tail = NULL; +} + +void posix_slist_append(posix_slist_t *list, posix_snode_t *node) { + node->next = NULL; + if (list->tail) { + list->tail->next = node; + } else { + list->head = node; + } + list->tail = node; +} + +void posix_slist_remove(posix_slist_t *list, posix_snode_t *prev, posix_snode_t *node) { + if (prev) { + prev->next = node->next; + } else { + list->head = node->next; + } + if (list->tail == node) { + list->tail = prev; + } +} diff --git a/src/shared/platform/posix/ocre_internal.cmake b/src/shared/platform/posix/ocre_internal.cmake index 41ed1fb2..da1e7823 100644 --- a/src/shared/platform/posix/ocre_internal.cmake +++ b/src/shared/platform/posix/ocre_internal.cmake @@ -77,6 +77,7 @@ set(lib_sources ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_misc.c ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_memory.c ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_timer.c + ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_slist.c # APIs ${OCRE_ROOT_DIR}/src/ocre/api/ocre_api.c ${OCRE_ROOT_DIR}/src/ocre/api/ocre_common.c From 3913749c4861d1ccb24ce9867f614b54cfa6fcad Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 12:00:15 +0200 Subject: [PATCH 07/26] Rename slist and add commentary Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 8 ++--- src/shared/platform/posix/core_internal.h | 41 ++++++++++++++++++----- src/shared/platform/posix/core_slist.c | 13 +++++-- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index b5ee0cdf..c88e54e6 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -103,7 +103,7 @@ typedef struct module_node { posix_snode_t node; } module_node_t; -static posix_slist_t module_registry; +static core_slist_t module_registry; static core_mutex_t registry_mutex; /* POSIX-specific macros */ @@ -378,7 +378,7 @@ int ocre_common_init(void) { } #else /* POSIX */ core_mutex_init(®istry_mutex); - posix_slist_init(&module_registry); + core_slist_init(&module_registry); if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); return -EINVAL; @@ -469,7 +469,7 @@ int ocre_register_module(wasm_module_inst_t module_inst) { core_mutex_unlock(®istry_mutex); #else core_mutex_lock(®istry_mutex); - posix_slist_append(&module_registry, &node->node); + core_slist_append(&module_registry, &node->node); core_mutex_unlock(®istry_mutex); #endif @@ -509,7 +509,7 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { if (node->ctx.exec_env) { wasm_runtime_destroy_exec_env(node->ctx.exec_env); } - posix_slist_remove(&module_registry, prev ? &prev->node : NULL, &node->node); + core_slist_remove(&module_registry, prev ? &prev->node : NULL, &node->node); core_free(node); LOG_INF("Module unregistered: %p", (void *)module_inst); break; diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index 8a9cef65..aad9e723 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -157,19 +157,44 @@ struct core_timer { void *user_data; /*!< User data for the callback */ }; -/* POSIX simple linked list implementation */ +/** + * @brief Structure representing a node in a singly-linked list. + */ typedef struct posix_snode { - struct posix_snode *next; + struct posix_snode *next; /*!< Pointer to the next node in the list */ } posix_snode_t; +/** + * @brief Structure representing a singly-linked list for POSIX platform. + */ typedef struct { - posix_snode_t *head; - posix_snode_t *tail; -} posix_slist_t; + posix_snode_t *head; /*!< Pointer to the first node in the list */ + posix_snode_t *tail; /*!< Pointer to the last node in the list */ +} core_slist_t; + +/** + * @brief Initialize a singly-linked list. + * + * @param list Pointer to the list to initialize. + */ +void core_slist_init(core_slist_t *list); -void posix_slist_init(posix_slist_t *list); -void posix_slist_append(posix_slist_t *list, posix_snode_t *node); -void posix_slist_remove(posix_slist_t *list, posix_snode_t *prev, posix_snode_t *node); +/** + * @brief Append a node to the end of a singly-linked list. + * + * @param list Pointer to the list to append to. + * @param node Pointer to the node to append. + */ +void core_slist_append(core_slist_t *list, posix_snode_t *node); + +/** + * @brief Remove a node from a singly-linked list. + * + * @param list Pointer to the list to remove from. + * @param prev Pointer to the previous node (or NULL if removing head). + * @param node Pointer to the node to remove. + */ +void core_slist_remove(core_slist_t *list, posix_snode_t *prev, posix_snode_t *node); #endif /* OCRE_CORE_INTERNAL_H */ diff --git a/src/shared/platform/posix/core_slist.c b/src/shared/platform/posix/core_slist.c index 023d8566..fb09f721 100644 --- a/src/shared/platform/posix/core_slist.c +++ b/src/shared/platform/posix/core_slist.c @@ -1,11 +1,18 @@ +/** + * @copyright Copyright © contributors to Project Ocre, + * which has been established as Project Ocre a Series of LF Projects, LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + #include "ocre_core_external.h" -void posix_slist_init(posix_slist_t *list) { +void core_slist_init(core_slist_t *list) { list->head = NULL; list->tail = NULL; } -void posix_slist_append(posix_slist_t *list, posix_snode_t *node) { +void core_slist_append(core_slist_t *list, posix_snode_t *node) { node->next = NULL; if (list->tail) { list->tail->next = node; @@ -15,7 +22,7 @@ void posix_slist_append(posix_slist_t *list, posix_snode_t *node) { list->tail = node; } -void posix_slist_remove(posix_slist_t *list, posix_snode_t *prev, posix_snode_t *node) { +void core_slist_remove(core_slist_t *list, posix_snode_t *prev, posix_snode_t *node) { if (prev) { prev->next = node->next; } else { From 748051c65f55802d207fe1577c91808c8fb23628 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 12:18:17 +0200 Subject: [PATCH 08/26] Finalize snode platformization Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 16 +++++----- src/shared/platform/posix/core_internal.h | 14 ++++----- src/shared/platform/posix/core_slist.c | 4 +-- src/shared/platform/zephyr/core_internal.h | 34 ++++++++++++++++++++++ 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index c88e54e6..7bd8293b 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -58,10 +58,10 @@ struct k_spinlock ocre_event_queue_lock; typedef struct module_node { ocre_module_context_t ctx; - sys_snode_t node; + core_snode_t node; } module_node_t; -static sys_slist_t module_registry; +static core_slist_t module_registry; static core_mutex_t registry_mutex; /* Zephyr-specific macros */ @@ -100,7 +100,7 @@ static posix_spinlock_t ocre_event_queue_lock; typedef struct module_node { ocre_module_context_t ctx; - posix_snode_t node; + core_snode_t node; } module_node_t; static core_slist_t module_registry; @@ -366,7 +366,7 @@ int ocre_common_init(void) { #ifdef __ZEPHYR__ core_mutex_init(®istry_mutex); - sys_slist_init(&module_registry); + core_slist_init(&module_registry); if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); return -EINVAL; @@ -465,7 +465,7 @@ int ocre_register_module(wasm_module_inst_t module_inst) { #ifdef __ZEPHYR__ core_mutex_lock(®istry_mutex); - sys_slist_append(&module_registry, &node->node); + core_slist_append(&module_registry, &node->node); core_mutex_unlock(®istry_mutex); #else core_mutex_lock(®istry_mutex); @@ -492,7 +492,7 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { if (node->ctx.exec_env) { wasm_runtime_destroy_exec_env(node->ctx.exec_env); } - sys_slist_remove(&module_registry, NULL, &node->node); + core_slist_remove(&module_registry, NULL, &node->node); k_free(node); LOG_INF("Module unregistered: %p", (void *)module_inst); break; @@ -532,7 +532,7 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { #ifdef __ZEPHYR__ core_mutex_lock(®istry_mutex); - for (sys_snode_t *current = module_registry.head; current != NULL; current = current->next) { + for (core_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { @@ -545,7 +545,7 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { core_mutex_unlock(®istry_mutex); #else core_mutex_lock(®istry_mutex); - for (posix_snode_t *current = module_registry.head; current != NULL; current = current->next) { + for (core_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index aad9e723..aace913e 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -160,16 +160,16 @@ struct core_timer { /** * @brief Structure representing a node in a singly-linked list. */ -typedef struct posix_snode { - struct posix_snode *next; /*!< Pointer to the next node in the list */ -} posix_snode_t; +typedef struct core_snode { + struct core_snode *next; /*!< Pointer to the next node in the list */ +} core_snode_t; /** * @brief Structure representing a singly-linked list for POSIX platform. */ typedef struct { - posix_snode_t *head; /*!< Pointer to the first node in the list */ - posix_snode_t *tail; /*!< Pointer to the last node in the list */ + core_snode_t *head; /*!< Pointer to the first node in the list */ + core_snode_t *tail; /*!< Pointer to the last node in the list */ } core_slist_t; /** @@ -185,7 +185,7 @@ void core_slist_init(core_slist_t *list); * @param list Pointer to the list to append to. * @param node Pointer to the node to append. */ -void core_slist_append(core_slist_t *list, posix_snode_t *node); +void core_slist_append(core_slist_t *list, core_snode_t *node); /** * @brief Remove a node from a singly-linked list. @@ -194,7 +194,7 @@ void core_slist_append(core_slist_t *list, posix_snode_t *node); * @param prev Pointer to the previous node (or NULL if removing head). * @param node Pointer to the node to remove. */ -void core_slist_remove(core_slist_t *list, posix_snode_t *prev, posix_snode_t *node); +void core_slist_remove(core_slist_t *list, core_snode_t *prev, core_snode_t *node); #endif /* OCRE_CORE_INTERNAL_H */ diff --git a/src/shared/platform/posix/core_slist.c b/src/shared/platform/posix/core_slist.c index fb09f721..1def4404 100644 --- a/src/shared/platform/posix/core_slist.c +++ b/src/shared/platform/posix/core_slist.c @@ -12,7 +12,7 @@ void core_slist_init(core_slist_t *list) { list->tail = NULL; } -void core_slist_append(core_slist_t *list, posix_snode_t *node) { +void core_slist_append(core_slist_t *list, core_snode_t *node) { node->next = NULL; if (list->tail) { list->tail->next = node; @@ -22,7 +22,7 @@ void core_slist_append(core_slist_t *list, posix_snode_t *node) { list->tail = node; } -void core_slist_remove(core_slist_t *list, posix_snode_t *prev, posix_snode_t *node) { +void core_slist_remove(core_slist_t *list, core_snode_t *prev, core_snode_t *node) { if (prev) { prev->next = node->next; } else { diff --git a/src/shared/platform/zephyr/core_internal.h b/src/shared/platform/zephyr/core_internal.h index 87e0cddb..d5ba9e8b 100644 --- a/src/shared/platform/zephyr/core_internal.h +++ b/src/shared/platform/zephyr/core_internal.h @@ -120,4 +120,38 @@ struct core_timer { void *user_data; /*!< User data for the callback */ }; +/** + * @brief Structure representing a node in a singly-linked list. + */ +#define core_snode_t sys_snode_t + +/** + * @brief Structure representing a singly-linked list for POSIX platform. + */ +#define core_slist_t sys_slist_t + +/** + * @brief Initialize a singly-linked list. + * + * @param list Pointer to the list to initialize. + */ +#define core_slist_init sys_slist_init + +/** + * @brief Append a node to the end of a singly-linked list. + * + * @param list Pointer to the list to append to. + * @param node Pointer to the node to append. + */ +#define core_slist_append sys_slist_append + +/** + * @brief Remove a node from a singly-linked list. + * + * @param list Pointer to the list to remove from. + * @param prev Pointer to the previous node (or NULL if removing head). + * @param node Pointer to the node to remove. + */ +#define core_slist_remove sys_slist_remove + #endif From 3d47af6c53bb22925888bb612c0f693bb7f87876 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 12:28:26 +0200 Subject: [PATCH 09/26] Further cleanup Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 51 +++++++++++--------------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 7bd8293b..7a819b2e 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -44,6 +44,14 @@ LOG_MODULE_REGISTER(ocre_common, LOG_LEVEL_DBG); #include "ocre_common.h" +typedef struct module_node { + ocre_module_context_t ctx; + core_snode_t node; +} module_node_t; + +static core_slist_t module_registry; +static core_mutex_t registry_mutex; + /* Platform-specific abstractions */ #ifdef __ZEPHYR__ @@ -56,14 +64,6 @@ K_MSGQ_DEFINE(ocre_event_queue, sizeof(ocre_event_t), SIZE_OCRE_EVENT_BUFFER, 4) bool ocre_event_queue_initialized = false; struct k_spinlock ocre_event_queue_lock; -typedef struct module_node { - ocre_module_context_t ctx; - core_snode_t node; -} module_node_t; - -static core_slist_t module_registry; -static core_mutex_t registry_mutex; - /* Zephyr-specific macros */ #define OCRE_UPTIME_GET() k_uptime_get_32() #define OCRE_SPINLOCK_LOCK(lock) k_spin_lock(lock) @@ -98,14 +98,6 @@ static posix_msgq_t ocre_event_queue; bool ocre_event_queue_initialized = false; static posix_spinlock_t ocre_event_queue_lock; -typedef struct module_node { - ocre_module_context_t ctx; - core_snode_t node; -} module_node_t; - -static core_slist_t module_registry; -static core_mutex_t registry_mutex; - /* POSIX-specific macros */ #define OCRE_UPTIME_GET() posix_uptime_get() #define OCRE_SPINLOCK_LOCK(lock) posix_spinlock_lock(lock) @@ -254,21 +246,21 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o int ret; #ifdef __ZEPHYR__ - k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); + k_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); ret = k_msgq_peek(&ocre_event_queue, &event); if (ret != 0) { - k_spin_unlock(&ocre_event_queue_lock, key); + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); return -ENOMSG; } if (event.owner != module_inst) { - k_spin_unlock(&ocre_event_queue_lock, key); + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); return -EPERM; } ret = k_msgq_get(&ocre_event_queue, &event, K_FOREVER); if (ret != 0) { - k_spin_unlock(&ocre_event_queue_lock, key); + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); return -ENOENT; } #else /* POSIX */ @@ -341,7 +333,7 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o */ default: { #ifdef __ZEPHYR__ - k_spin_unlock(&ocre_event_queue_lock, key); + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); #else OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); #endif @@ -350,7 +342,7 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o } } #ifdef __ZEPHYR__ - k_spin_unlock(&ocre_event_queue_lock, key); + OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); #else OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); #endif @@ -530,20 +522,6 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { int count = 0; -#ifdef __ZEPHYR__ - core_mutex_lock(®istry_mutex); - for (core_snode_t *current = module_registry.head; current != NULL; current = current->next) { - module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); - LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); - if (node->ctx.inst == module_inst) { - node->ctx.last_activity = k_uptime_get_32(); - core_mutex_unlock(®istry_mutex); - LOG_DBG("Found module context for %p", (void *)module_inst); - return &node->ctx; - } - } - core_mutex_unlock(®istry_mutex); -#else core_mutex_lock(®istry_mutex); for (core_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); @@ -556,7 +534,6 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { } } core_mutex_unlock(®istry_mutex); -#endif LOG_ERR("Module context not found for %p", (void *)module_inst); return NULL; From 859a50deb153e6552bd250fdb2f9e9443d1e9203 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 13:02:46 +0200 Subject: [PATCH 10/26] Cleanup Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 37 +--------------------- src/shared/platform/posix/core_internal.h | 16 +++++++++- src/shared/platform/zephyr/core_internal.h | 4 +++ 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 7a819b2e..6c743b97 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -176,17 +176,6 @@ static int posix_msgq_put(posix_msgq_t *msgq, const ocre_event_t *event) { return 0; } -#define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(list, var, tmp, member) \ - for (var = (module_node_t *)((list)->head), \ - tmp = var ? (module_node_t *)(var->node.next) : NULL; \ - var; \ - var = tmp, tmp = tmp ? (module_node_t *)(tmp->node.next) : NULL) - -#define SYS_SLIST_FOR_EACH_CONTAINER(list, var, member) \ - for (var = (module_node_t *)((list)->head); \ - var; \ - var = (module_node_t *)(var->node.next)) - #endif /* __ZEPHYR__ */ static struct cleanup_handler { @@ -455,15 +444,9 @@ int ocre_register_module(wasm_module_inst_t module_inst) { memset(node->ctx.resource_count, 0, sizeof(node->ctx.resource_count)); memset(node->ctx.dispatchers, 0, sizeof(node->ctx.dispatchers)); -#ifdef __ZEPHYR__ - core_mutex_lock(®istry_mutex); - core_slist_append(&module_registry, &node->node); - core_mutex_unlock(®istry_mutex); -#else core_mutex_lock(®istry_mutex); core_slist_append(&module_registry, &node->node); core_mutex_unlock(®istry_mutex); -#endif LOG_INF("Module registered: %p", (void *)module_inst); return 0; @@ -475,27 +458,10 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { return; } -#ifdef __ZEPHYR__ - core_mutex_lock(®istry_mutex); - module_node_t *node, *tmp; - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { - if (node->ctx.inst == module_inst) { - ocre_cleanup_module_resources(module_inst); - if (node->ctx.exec_env) { - wasm_runtime_destroy_exec_env(node->ctx.exec_env); - } - core_slist_remove(&module_registry, NULL, &node->node); - k_free(node); - LOG_INF("Module unregistered: %p", (void *)module_inst); - break; - } - } - core_mutex_unlock(®istry_mutex); -#else core_mutex_lock(®istry_mutex); module_node_t *node, *tmp; module_node_t *prev = NULL; - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { + CORE_SLIST_FOR_EACH_CONTAINER_SAFE(&module_registry, node, tmp, node) { if (node->ctx.inst == module_inst) { ocre_cleanup_module_resources(module_inst); if (node->ctx.exec_env) { @@ -509,7 +475,6 @@ void ocre_unregister_module(wasm_module_inst_t module_inst) { prev = node; } core_mutex_unlock(®istry_mutex); -#endif } ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index aace913e..d2787548 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -157,6 +157,21 @@ struct core_timer { void *user_data; /*!< User data for the callback */ }; +/* Generic singly-linked list iteration macros */ +#define CONTAINER_OF(ptr, type, member) \ + ((type *)((char *)(ptr) - offsetof(type, member))) + +#define CORE_SLIST_FOR_EACH_CONTAINER_SAFE(list, var, tmp, member) \ + for (var = (list)->head ? CONTAINER_OF((list)->head, __typeof__(*var), member) : NULL, \ + tmp = var ? (var->member.next ? CONTAINER_OF(var->member.next, __typeof__(*var), member) : NULL) : NULL; \ + var; \ + var = tmp, tmp = tmp ? (tmp->member.next ? CONTAINER_OF(tmp->member.next, __typeof__(*var), member) : NULL) : NULL) + +#define CORE_SLIST_FOR_EACH_CONTAINER(list, var, member) \ + for (var = (list)->head ? CONTAINER_OF((list)->head, __typeof__(*var), member) : NULL; \ + var; \ + var = var->member.next ? CONTAINER_OF(var->member.next, __typeof__(*var), member) : NULL) + /** * @brief Structure representing a node in a singly-linked list. */ @@ -196,5 +211,4 @@ void core_slist_append(core_slist_t *list, core_snode_t *node); */ void core_slist_remove(core_slist_t *list, core_snode_t *prev, core_snode_t *node); - #endif /* OCRE_CORE_INTERNAL_H */ diff --git a/src/shared/platform/zephyr/core_internal.h b/src/shared/platform/zephyr/core_internal.h index d5ba9e8b..478fb903 100644 --- a/src/shared/platform/zephyr/core_internal.h +++ b/src/shared/platform/zephyr/core_internal.h @@ -120,6 +120,10 @@ struct core_timer { void *user_data; /*!< User data for the callback */ }; +/* Generic singly-linked list iteration macros */ +#define CORE_SLIST_FOR_EACH_CONTAINER_SAFE SYS_SLIST_FOR_EACH_CONTAINER_SAFE +#define CORE_SLIST_FOR_EACH_CONTAINER SYS_SLIST_FOR_EACH_CONTAINER + /** * @brief Structure representing a node in a singly-linked list. */ From 0e546c1518498ae81f70dfeda55a004282882d2f Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:05:44 +0200 Subject: [PATCH 11/26] Platformize spinlocks and misc cleanup Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 133 ++++----------------- src/shared/platform/ocre_core_external.h | 4 + src/shared/platform/posix/core_internal.h | 9 ++ src/shared/platform/posix/core_misc.c | 16 +++ src/shared/platform/zephyr/core_internal.h | 8 ++ 5 files changed, 60 insertions(+), 110 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 6c743b97..8547b729 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -14,27 +14,7 @@ #include #include -#ifdef __ZEPHYR__ -#include -#include -#include -#include -#include -#include -#include LOG_MODULE_REGISTER(ocre_common, LOG_LEVEL_DBG); -#else /* POSIX */ -#include -#include -#include -#include -#include -#include -/* POSIX logging macros are already defined in core_internal.h */ -#endif - -#include "../../../../../wasm-micro-runtime/core/iwasm/include/lib_export.h" -#include "bh_log.h" #ifdef __ZEPHYR__ #include "../ocre_gpio/ocre_gpio.h" @@ -62,12 +42,9 @@ char *ocre_event_queue_buffer_ptr = ocre_event_queue_buffer; K_MSGQ_DEFINE(ocre_event_queue, sizeof(ocre_event_t), SIZE_OCRE_EVENT_BUFFER, 4); bool ocre_event_queue_initialized = false; -struct k_spinlock ocre_event_queue_lock; +core_spinlock_t ocre_event_queue_lock; + -/* Zephyr-specific macros */ -#define OCRE_UPTIME_GET() k_uptime_get_32() -#define OCRE_SPINLOCK_LOCK(lock) k_spin_lock(lock) -#define OCRE_SPINLOCK_UNLOCK(lock, key) k_spin_unlock(lock, key) #else /* POSIX */ @@ -84,58 +61,12 @@ typedef struct { pthread_cond_t cond; } posix_msgq_t; -/* POSIX spinlock simulation using mutex */ -typedef struct { - pthread_mutex_t mutex; -} posix_spinlock_t; - -typedef int posix_spinlock_key_t; - static char ocre_event_queue_buffer[SIZE_OCRE_EVENT_BUFFER * sizeof(ocre_event_t)]; char *ocre_event_queue_buffer_ptr = ocre_event_queue_buffer; static posix_msgq_t ocre_event_queue; bool ocre_event_queue_initialized = false; -static posix_spinlock_t ocre_event_queue_lock; - -/* POSIX-specific macros */ -#define OCRE_UPTIME_GET() posix_uptime_get() -#define OCRE_SPINLOCK_LOCK(lock) posix_spinlock_lock(lock) -#define OCRE_SPINLOCK_UNLOCK(lock, key) posix_spinlock_unlock(lock, key) - -/* POSIX error codes compatibility */ -#ifndef EINVAL -#define EINVAL 22 -#endif -#ifndef ENOMSG -#define ENOMSG 42 -#endif -#ifndef EPERM -#define EPERM 1 -#endif -#ifndef ENOENT -#define ENOENT 2 -#endif -#ifndef ENOMEM -#define ENOMEM 12 -#endif - -/* POSIX helper functions */ -static uint32_t posix_uptime_get(void) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (uint32_t)(ts.tv_sec * 1000 + ts.tv_nsec / 1000000); -} - -static posix_spinlock_key_t posix_spinlock_lock(posix_spinlock_t *lock) { - pthread_mutex_lock(&lock->mutex); - return 0; -} - -static void posix_spinlock_unlock(posix_spinlock_t *lock, posix_spinlock_key_t key) { - (void)key; - pthread_mutex_unlock(&lock->mutex); -} +static core_spinlock_t ocre_event_queue_lock; static int posix_msgq_init(posix_msgq_t *msgq, size_t item_size, size_t max_items) { msgq->buffer = (ocre_event_t *)ocre_event_queue_buffer; @@ -235,39 +166,39 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o int ret; #ifdef __ZEPHYR__ - k_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); ret = k_msgq_peek(&ocre_event_queue, &event); if (ret != 0) { - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); return -ENOMSG; } if (event.owner != module_inst) { - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); return -EPERM; } ret = k_msgq_get(&ocre_event_queue, &event, K_FOREVER); if (ret != 0) { - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); return -ENOENT; } #else /* POSIX */ - posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); ret = posix_msgq_peek(&ocre_event_queue, &event); if (ret != 0) { - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); return -ENOMSG; } if (event.owner != module_inst) { - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); return -EPERM; } ret = posix_msgq_get(&ocre_event_queue, &event); if (ret != 0) { - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); return -ENOENT; } #endif @@ -321,20 +252,12 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o ================================= */ default: { -#ifdef __ZEPHYR__ - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); -#else - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); -#endif + core_spinlock_unlock(&ocre_event_queue_lock, key); LOG_ERR("Invalid event type: %u", event.type); return -EINVAL; } } -#ifdef __ZEPHYR__ - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); -#else - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); -#endif + core_spinlock_unlock(&ocre_event_queue_lock, key); return 0; } @@ -440,7 +363,7 @@ int ocre_register_module(wasm_module_inst_t module_inst) { return -ENOMEM; } node->ctx.in_use = true; - node->ctx.last_activity = OCRE_UPTIME_GET(); + node->ctx.last_activity = core_uptime_get(); memset(node->ctx.resource_count, 0, sizeof(node->ctx.resource_count)); memset(node->ctx.dispatchers, 0, sizeof(node->ctx.dispatchers)); @@ -492,7 +415,7 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { - node->ctx.last_activity = OCRE_UPTIME_GET(); + node->ctx.last_activity = core_uptime_get(); core_mutex_unlock(®istry_mutex); LOG_DBG("Found module context for %p", (void *)module_inst); return &node->ctx; @@ -877,13 +800,13 @@ static void timer_callback_wrapper(struct k_timer *timer) { LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, event.data.timer_event.timer_id, (void *)timers[i].owner); LOG_DBG("Event address: %p, Queue buffer: %p", (void *)&event, (void *)ocre_event_queue_buffer_ptr); - k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { LOG_ERR("Failed to queue timer event for timer %d", timers[i].id); } else { LOG_DBG("Queued timer event for timer %d", timers[i].id); } - k_spin_unlock(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); } } } @@ -917,13 +840,13 @@ static void posix_send_timer_event(int timer_id) { LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer_id, (void *)timers[index].owner); - posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); if (posix_msgq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue timer event for timer %d", timer_id); } else { LOG_DBG("Queued timer event for timer %d", timer_id); } - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); } #endif @@ -1143,22 +1066,13 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ LOG_DBG("Creating messaging event: ID=%d, topic=%s, content_type=%s, payload_len=%d for module %p", message_id, (char *)topic, (char *)content_type, payload_len, (void *)target_module); - + + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); #ifdef __ZEPHYR__ - k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { - LOG_ERR("Failed to queue messaging event for message ID %d", message_id); - wasm_runtime_module_free(target_module, topic_offset); - wasm_runtime_module_free(target_module, content_offset); - wasm_runtime_module_free(target_module, payload_offset); - } else { - message_sent = true; - LOG_DBG("Queued messaging event for message ID %d", message_id); - } - k_spin_unlock(&ocre_event_queue_lock, key); #else - posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); if (posix_msgq_put(&ocre_event_queue, &event) != 0) { +#endif LOG_ERR("Failed to queue messaging event for message ID %d", message_id); wasm_runtime_module_free(target_module, topic_offset); wasm_runtime_module_free(target_module, content_offset); @@ -1167,8 +1081,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ message_sent = true; LOG_DBG("Queued messaging event for message ID %d", message_id); } - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); -#endif + core_spinlock_unlock(&ocre_event_queue_lock, key); } core_mutex_unlock(&messaging_system.mutex); diff --git a/src/shared/platform/ocre_core_external.h b/src/shared/platform/ocre_core_external.h index c38b8c27..593a7497 100644 --- a/src/shared/platform/ocre_core_external.h +++ b/src/shared/platform/ocre_core_external.h @@ -223,4 +223,8 @@ int core_fileclose(void *handle); */ int core_construct_filepath(char *path, size_t len, char *name); +uint32_t core_uptime_get(void); +core_spinlock_key_t core_spinlock_lock(core_spinlock_t *lock); +void core_spinlock_unlock(core_spinlock_t *lock, core_spinlock_key_t key); + #endif /* OCRE_CORE_EXTERNAL_H */ diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index d2787548..032e39c8 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -10,9 +10,11 @@ #include #include +#include #include #include #include +#include #include @@ -211,4 +213,11 @@ void core_slist_append(core_slist_t *list, core_snode_t *node); */ void core_slist_remove(core_slist_t *list, core_snode_t *prev, core_snode_t *node); +/* POSIX spinlock simulation using mutex */ +typedef struct { + pthread_mutex_t mutex; +} core_spinlock_t; + +typedef int core_spinlock_key_t; + #endif /* OCRE_CORE_INTERNAL_H */ diff --git a/src/shared/platform/posix/core_misc.c b/src/shared/platform/posix/core_misc.c index f556c5a9..069c1735 100644 --- a/src/shared/platform/posix/core_misc.c +++ b/src/shared/platform/posix/core_misc.c @@ -38,3 +38,19 @@ void core_sleep_ms(int milliseconds) void core_yield(void) { sched_yield(); } + +uint32_t core_uptime_get(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint32_t)(ts.tv_sec * 1000 + ts.tv_nsec / 1000000); +} + +core_spinlock_key_t core_spinlock_lock(core_spinlock_t *lock) { + pthread_mutex_lock(&lock->mutex); + return 0; +} + +void core_spinlock_unlock(core_spinlock_t *lock, core_spinlock_key_t key) { + (void)key; + pthread_mutex_unlock(&lock->mutex); +} diff --git a/src/shared/platform/zephyr/core_internal.h b/src/shared/platform/zephyr/core_internal.h index 478fb903..f8bc9f88 100644 --- a/src/shared/platform/zephyr/core_internal.h +++ b/src/shared/platform/zephyr/core_internal.h @@ -158,4 +158,12 @@ struct core_timer { */ #define core_slist_remove sys_slist_remove +/* Zephyr-specific macros */ +#define core_uptime_get k_uptime_get_32 +#define core_spinlock_lock k_spin_lock +#define core_spinlock_unlock k_spin_unlock + +typedef struct k_spinlock core_spinlock_t; +typedef k_spinlock_key_t core_spinlock_key_t; + #endif From d582bc2abebdb0c5183547ed8191cf07e493fbe3 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:10:00 +0200 Subject: [PATCH 12/26] Add missing comments Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/shared/platform/ocre_core_external.h | 19 +++++++++++++++ src/shared/platform/posix/core_internal.h | 9 ++++++-- src/shared/platform/zephyr/core_internal.h | 27 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/shared/platform/ocre_core_external.h b/src/shared/platform/ocre_core_external.h index 593a7497..49b92757 100644 --- a/src/shared/platform/ocre_core_external.h +++ b/src/shared/platform/ocre_core_external.h @@ -223,8 +223,27 @@ int core_fileclose(void *handle); */ int core_construct_filepath(char *path, size_t len, char *name); +/** + * @brief Get system uptime in milliseconds. + * + * @return System uptime in milliseconds. + */ uint32_t core_uptime_get(void); + +/** + * @brief Lock a spinlock and return the interrupt key. + * + * @param lock Pointer to the spinlock structure. + * @return Interrupt key to be used with unlock. + */ core_spinlock_key_t core_spinlock_lock(core_spinlock_t *lock); + +/** + * @brief Unlock a spinlock using the interrupt key. + * + * @param lock Pointer to the spinlock structure. + * @param key Interrupt key returned from lock operation. + */ void core_spinlock_unlock(core_spinlock_t *lock, core_spinlock_key_t key); #endif /* OCRE_CORE_EXTERNAL_H */ diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index 032e39c8..a22e027a 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -213,11 +213,16 @@ void core_slist_append(core_slist_t *list, core_snode_t *node); */ void core_slist_remove(core_slist_t *list, core_snode_t *prev, core_snode_t *node); -/* POSIX spinlock simulation using mutex */ +/** + * @brief Spinlock type for POSIX platform (simulated using mutex). + */ typedef struct { - pthread_mutex_t mutex; + pthread_mutex_t mutex; /*!< POSIX mutex for spinlock simulation */ } core_spinlock_t; +/** + * @brief Spinlock key type for POSIX platform. + */ typedef int core_spinlock_key_t; #endif /* OCRE_CORE_INTERNAL_H */ diff --git a/src/shared/platform/zephyr/core_internal.h b/src/shared/platform/zephyr/core_internal.h index f8bc9f88..c148841c 100644 --- a/src/shared/platform/zephyr/core_internal.h +++ b/src/shared/platform/zephyr/core_internal.h @@ -159,11 +159,38 @@ struct core_timer { #define core_slist_remove sys_slist_remove /* Zephyr-specific macros */ + +/** + * @brief Get system uptime in milliseconds. + * + * @return System uptime in milliseconds. + */ #define core_uptime_get k_uptime_get_32 + +/** + * @brief Lock a spinlock and return the interrupt key. + * + * @param lock Pointer to the spinlock structure. + * @return Interrupt key to be used with unlock. + */ #define core_spinlock_lock k_spin_lock + +/** + * @brief Unlock a spinlock using the interrupt key. + * + * @param lock Pointer to the spinlock structure. + * @param key Interrupt key returned from lock operation. + */ #define core_spinlock_unlock k_spin_unlock +/** + * @brief Spinlock type for Zephyr platform. + */ typedef struct k_spinlock core_spinlock_t; + +/** + * @brief Spinlock key type for Zephyr platform. + */ typedef k_spinlock_key_t core_spinlock_key_t; #endif From 6e895b145c96278ca0d393eccafbad2382a7da38 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:45:53 +0200 Subject: [PATCH 13/26] Create eventq modules Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 141 +++--------------- src/ocre/api/ocre_common.h | 11 +- src/ocre/ocre_gpio/ocre_gpio.c | 8 +- src/shared/platform/ocre_core_external.h | 44 ++++++ src/shared/platform/posix/core_eventq.c | 74 +++++++++ src/shared/platform/posix/core_internal.h | 17 +++ src/shared/platform/posix/ocre_internal.cmake | 1 + src/shared/platform/zephyr/core_eventq.c | 64 ++++++++ src/shared/platform/zephyr/core_internal.h | 13 ++ .../platform/zephyr/ocre_internal.cmake | 1 + 10 files changed, 240 insertions(+), 134 deletions(-) create mode 100644 src/shared/platform/posix/core_eventq.c create mode 100644 src/shared/platform/zephyr/core_eventq.c diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 8547b729..77c3ba38 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -32,83 +32,13 @@ typedef struct module_node { static core_slist_t module_registry; static core_mutex_t registry_mutex; -/* Platform-specific abstractions */ -#ifdef __ZEPHYR__ - #define SIZE_OCRE_EVENT_BUFFER 32 -__attribute__((section(".noinit.ocre_event_queue"), - aligned(8))) char ocre_event_queue_buffer[SIZE_OCRE_EVENT_BUFFER * sizeof(ocre_event_t)]; -char *ocre_event_queue_buffer_ptr = ocre_event_queue_buffer; -K_MSGQ_DEFINE(ocre_event_queue, sizeof(ocre_event_t), SIZE_OCRE_EVENT_BUFFER, 4); +/* Unified event queue implementation */ +core_eventq_t ocre_event_queue; bool ocre_event_queue_initialized = false; core_spinlock_t ocre_event_queue_lock; - - -#else /* POSIX */ - -#define SIZE_OCRE_EVENT_BUFFER 32 - -/* POSIX message queue simulation */ -typedef struct { - ocre_event_t *buffer; - size_t size; - size_t count; - size_t head; - size_t tail; - pthread_mutex_t mutex; - pthread_cond_t cond; -} posix_msgq_t; - -static char ocre_event_queue_buffer[SIZE_OCRE_EVENT_BUFFER * sizeof(ocre_event_t)]; -char *ocre_event_queue_buffer_ptr = ocre_event_queue_buffer; - -static posix_msgq_t ocre_event_queue; -bool ocre_event_queue_initialized = false; -static core_spinlock_t ocre_event_queue_lock; - -static int posix_msgq_init(posix_msgq_t *msgq, size_t item_size, size_t max_items) { - msgq->buffer = (ocre_event_t *)ocre_event_queue_buffer; - msgq->size = max_items; - msgq->count = 0; - msgq->head = 0; - msgq->tail = 0; - pthread_mutex_init(&msgq->mutex, NULL); - pthread_cond_init(&msgq->cond, NULL); - return 0; -} - -static int posix_msgq_peek(posix_msgq_t *msgq, ocre_event_t *event) { - if (msgq->count == 0) { - return -ENOMSG; - } - *event = msgq->buffer[msgq->head]; - return 0; -} - -static int posix_msgq_get(posix_msgq_t *msgq, ocre_event_t *event) { - if (msgq->count == 0) { - return -ENOENT; - } - *event = msgq->buffer[msgq->head]; - msgq->head = (msgq->head + 1) % msgq->size; - msgq->count--; - return 0; -} - -static int posix_msgq_put(posix_msgq_t *msgq, const ocre_event_t *event) { - if (msgq->count >= msgq->size) { - return -ENOMEM; - } - msgq->buffer[msgq->tail] = *event; - msgq->tail = (msgq->tail + 1) % msgq->size; - msgq->count++; - return 0; -} - -#endif /* __ZEPHYR__ */ - static struct cleanup_handler { ocre_resource_type_t type; ocre_cleanup_handler_t handler; @@ -165,9 +95,9 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o ocre_event_t event; int ret; -#ifdef __ZEPHYR__ + /* Generic event queue implementation for both platforms */ core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - ret = k_msgq_peek(&ocre_event_queue, &event); + ret = core_eventq_peek(&ocre_event_queue, &event); if (ret != 0) { core_spinlock_unlock(&ocre_event_queue_lock, key); return -ENOMSG; @@ -178,30 +108,11 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o return -EPERM; } - ret = k_msgq_get(&ocre_event_queue, &event, K_FOREVER); + ret = core_eventq_get(&ocre_event_queue, &event); if (ret != 0) { core_spinlock_unlock(&ocre_event_queue_lock, key); return -ENOENT; } -#else /* POSIX */ - core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - ret = posix_msgq_peek(&ocre_event_queue, &event); - if (ret != 0) { - core_spinlock_unlock(&ocre_event_queue_lock, key); - return -ENOMSG; - } - - if (event.owner != module_inst) { - core_spinlock_unlock(&ocre_event_queue_lock, key); - return -EPERM; - } - - ret = posix_msgq_get(&ocre_event_queue, &event); - if (ret != 0) { - core_spinlock_unlock(&ocre_event_queue_lock, key); - return -ENOENT; - } -#endif // Send event correctly to WASM switch (event.type) { @@ -268,33 +179,26 @@ int ocre_common_init(void) { return 0; } -#ifdef __ZEPHYR__ core_mutex_init(®istry_mutex); core_slist_init(&module_registry); - if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { - LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); - return -EINVAL; - } - k_msgq_init(&ocre_event_queue, ocre_event_queue_buffer, sizeof(ocre_event_t), 64); + + core_eventq_init(&ocre_event_queue, sizeof(ocre_event_t), SIZE_OCRE_EVENT_BUFFER); + + /* Purge any stale events from queue */ ocre_event_t dummy; - while (k_msgq_get(&ocre_event_queue, &dummy, K_NO_WAIT) == 0) { + while (core_eventq_get(&ocre_event_queue, &dummy) == 0) { LOG_INF("Purged stale event from queue"); } + +#ifdef __ZEPHYR__ + /* No additional Zephyr-specific initialization needed */ #else /* POSIX */ - core_mutex_init(®istry_mutex); - core_slist_init(&module_registry); - if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { - LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); - return -EINVAL; - } - posix_msgq_init(&ocre_event_queue, sizeof(ocre_event_t), SIZE_OCRE_EVENT_BUFFER); pthread_mutex_init(&ocre_event_queue_lock.mutex, NULL); #endif ocre_event_queue_initialized = true; #if EVENT_THREAD_POOL_SIZE > 0 - LOG_INF("ocre_event_queue initialized at %p, size=%d, buffer=%p", (void *)&ocre_event_queue, sizeof(ocre_event_t), - (void *)ocre_event_queue_buffer_ptr); + LOG_INF("ocre_event_queue initialized at %p, size=%d", (void *)&ocre_event_queue, sizeof(ocre_event_t)); for (int i = 0; i < EVENT_THREAD_POOL_SIZE; i++) { event_args[i].index = i; char thread_name[16]; @@ -784,12 +688,8 @@ static void timer_callback_wrapper(struct k_timer *timer) { LOG_ERR("Null timer pointer in callback"); return; } - if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { - LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); - return; - } LOG_DBG("Timer callback for timer %p", (void *)timer); - LOG_DBG("ocre_event_queue at %p, buffer at %p", (void *)&ocre_event_queue, (void *)ocre_event_queue_buffer_ptr); + LOG_DBG("ocre_event_queue at %p", (void *)&ocre_event_queue); for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { if (timers[i].in_use && &timers[i].timer == timer && timers[i].owner) { ocre_event_t event; @@ -799,9 +699,8 @@ static void timer_callback_wrapper(struct k_timer *timer) { LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, event.data.timer_event.timer_id, (void *)timers[i].owner); - LOG_DBG("Event address: %p, Queue buffer: %p", (void *)&event, (void *)ocre_event_queue_buffer_ptr); core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { + if (core_eventq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue timer event for timer %d", timers[i].id); } else { LOG_DBG("Queued timer event for timer %d", timers[i].id); @@ -841,7 +740,7 @@ static void posix_send_timer_event(int timer_id) { LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer_id, (void *)timers[index].owner); core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - if (posix_msgq_put(&ocre_event_queue, &event) != 0) { + if (core_eventq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue timer event for timer %d", timer_id); } else { LOG_DBG("Queued timer event for timer %d", timer_id); @@ -1068,11 +967,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ message_id, (char *)topic, (char *)content_type, payload_len, (void *)target_module); core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); -#ifdef __ZEPHYR__ - if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { -#else - if (posix_msgq_put(&ocre_event_queue, &event) != 0) { -#endif + if (core_eventq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue messaging event for message ID %d", message_id); wasm_runtime_module_free(target_module, topic_offset); wasm_runtime_module_free(target_module, content_offset); diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index 457ebbbe..acffd5d5 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -11,6 +11,7 @@ #include #include #include +#include "ocre_core_external.h" /* Platform-specific includes */ #ifdef __ZEPHYR__ @@ -34,13 +35,9 @@ extern bool ocre_event_queue_initialized; extern __thread wasm_module_inst_t *current_module_tls; extern char *ocre_event_queue_buffer_ptr; // Defined in ocre_common.c -/* Platform-specific external declarations */ -#ifdef __ZEPHYR__ -extern struct k_msgq ocre_event_queue; // Defined in ocre_common.c -extern struct k_spinlock ocre_event_queue_lock; // Defined in ocre_common.c -#else -/* POSIX equivalents will be defined in the .c file */ -#endif +/* External declarations for unified event queue */ +extern core_eventq_t ocre_event_queue; // Defined in ocre_common.c +extern core_spinlock_t ocre_event_queue_lock; // Defined in ocre_common.c /** diff --git a/src/ocre/ocre_gpio/ocre_gpio.c b/src/ocre/ocre_gpio/ocre_gpio.c index f15a90a0..68e4ade7 100644 --- a/src/ocre/ocre_gpio/ocre_gpio.c +++ b/src/ocre/ocre_gpio/ocre_gpio.c @@ -370,14 +370,14 @@ static void gpio_callback_handler(const struct device *port, struct gpio_callbac event.data.gpio_event.port = gpio_pins[i].port_idx; event.data.gpio_event.state = (uint32_t)state; event.owner = gpio_pins[i].owner; - k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); - if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); + if (core_eventq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue GPIO event for pin %d", i); } else { LOG_INF("Queued GPIO event for pin %d (port=%d, pin=%d), state=%d", i, gpio_pins[i].port_idx, gpio_pins[i].pin_number, state); } - k_spin_unlock(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); } } } @@ -688,4 +688,4 @@ int ocre_gpio_wasm_unregister_callback_by_name(wasm_exec_env_t exec_env, const c LOG_INF("Unregistering callback by name: %s, global_pin=%d", name, global_pin); return ocre_gpio_unregister_callback(global_pin); -} \ No newline at end of file +} diff --git a/src/shared/platform/ocre_core_external.h b/src/shared/platform/ocre_core_external.h index 49b92757..69375219 100644 --- a/src/shared/platform/ocre_core_external.h +++ b/src/shared/platform/ocre_core_external.h @@ -246,4 +246,48 @@ core_spinlock_key_t core_spinlock_lock(core_spinlock_t *lock); */ void core_spinlock_unlock(core_spinlock_t *lock, core_spinlock_key_t key); +/** + * @brief Initialize an event queue with specified item size and capacity. + * + * @param eventq Pointer to the event queue structure to initialize. + * @param item_size Size of each item in bytes. + * @param max_items Maximum number of items the queue can hold. + * @return 0 on success, negative error code on failure. + */ +int core_eventq_init(core_eventq_t *eventq, size_t item_size, size_t max_items); + +/** + * @brief Peek at the next item in the queue without removing it. + * + * @param eventq Pointer to the event queue. + * @param event Pointer to buffer where the peeked item will be copied. + * @return 0 on success, -ENOMSG if queue is empty. + */ +int core_eventq_peek(core_eventq_t *eventq, void *event); + +/** + * @brief Get and remove the next item from the queue. + * + * @param eventq Pointer to the event queue. + * @param event Pointer to buffer where the retrieved item will be copied. + * @return 0 on success, -ENOENT if queue is empty. + */ +int core_eventq_get(core_eventq_t *eventq, void *event); + +/** + * @brief Put an item into the queue. + * + * @param eventq Pointer to the event queue. + * @param event Pointer to the item to be added to the queue. + * @return 0 on success, -ENOMEM if queue is full. + */ +int core_eventq_put(core_eventq_t *eventq, const void *event); + +/** + * @brief Destroy an event queue and free its resources. + * + * @param eventq Pointer to the event queue to destroy. + */ +void core_eventq_destroy(core_eventq_t *eventq); + #endif /* OCRE_CORE_EXTERNAL_H */ diff --git a/src/shared/platform/posix/core_eventq.c b/src/shared/platform/posix/core_eventq.c new file mode 100644 index 00000000..1146a371 --- /dev/null +++ b/src/shared/platform/posix/core_eventq.c @@ -0,0 +1,74 @@ +/** + * @copyright Copyright © contributors to Project Ocre, + * which has been established as Project Ocre a Series of LF Projects, LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ocre_core_external.h" +#include +#include + +int core_eventq_init(core_eventq_t *eventq, size_t item_size, size_t max_items) { + eventq->buffer = core_malloc(item_size * max_items); + if (!eventq->buffer) { + return -ENOMEM; + } + eventq->item_size = item_size; + eventq->max_items = max_items; + eventq->count = 0; + eventq->head = 0; + eventq->tail = 0; + pthread_mutex_init(&eventq->mutex, NULL); + pthread_cond_init(&eventq->cond, NULL); + return 0; +} + +int core_eventq_peek(core_eventq_t *eventq, void *event) { + pthread_mutex_lock(&eventq->mutex); + if (eventq->count == 0) { + pthread_mutex_unlock(&eventq->mutex); + return -ENOMSG; + } + memcpy(event, (char *)eventq->buffer + (eventq->head * eventq->item_size), eventq->item_size); + pthread_mutex_unlock(&eventq->mutex); + return 0; +} + +int core_eventq_get(core_eventq_t *eventq, void *event) { + pthread_mutex_lock(&eventq->mutex); + if (eventq->count == 0) { + pthread_mutex_unlock(&eventq->mutex); + return -ENOENT; + } + memcpy(event, (char *)eventq->buffer + (eventq->head * eventq->item_size), eventq->item_size); + eventq->head = (eventq->head + 1) % eventq->max_items; + eventq->count--; + pthread_mutex_unlock(&eventq->mutex); + return 0; +} + +int core_eventq_put(core_eventq_t *eventq, const void *event) { + pthread_mutex_lock(&eventq->mutex); + if (eventq->count >= eventq->max_items) { + pthread_mutex_unlock(&eventq->mutex); + return -ENOMEM; + } + memcpy((char *)eventq->buffer + (eventq->tail * eventq->item_size), event, eventq->item_size); + eventq->tail = (eventq->tail + 1) % eventq->max_items; + eventq->count++; + pthread_cond_signal(&eventq->cond); + pthread_mutex_unlock(&eventq->mutex); + return 0; +} + +void core_eventq_destroy(core_eventq_t *eventq) { + pthread_mutex_destroy(&eventq->mutex); + pthread_cond_destroy(&eventq->cond); + if (eventq->buffer) { + core_free(eventq->buffer); + eventq->buffer = NULL; + } +} + + diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index a22e027a..48a5eb25 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -225,4 +225,21 @@ typedef struct { */ typedef int core_spinlock_key_t; +/** + * @brief Generic event queue structure for POSIX platform. + * + * A thread-safe circular buffer implementation that can store + * any type of data items with configurable size and capacity. + */ +typedef struct { + void *buffer; /*!< Dynamically allocated buffer for queue items */ + size_t item_size; /*!< Size of each individual item in bytes */ + size_t max_items; /*!< Maximum number of items the queue can hold */ + size_t count; /*!< Current number of items in the queue */ + size_t head; /*!< Index of the next item to be read */ + size_t tail; /*!< Index where the next item will be written */ + pthread_mutex_t mutex; /*!< Mutex for thread-safe access */ + pthread_cond_t cond; /*!< Condition variable for signaling */ +} core_eventq_t; + #endif /* OCRE_CORE_INTERNAL_H */ diff --git a/src/shared/platform/posix/ocre_internal.cmake b/src/shared/platform/posix/ocre_internal.cmake index da1e7823..5bdcaaaa 100644 --- a/src/shared/platform/posix/ocre_internal.cmake +++ b/src/shared/platform/posix/ocre_internal.cmake @@ -78,6 +78,7 @@ set(lib_sources ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_memory.c ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_timer.c ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_slist.c + ${OCRE_ROOT_DIR}/src/shared/platform/posix/core_eventq.c # APIs ${OCRE_ROOT_DIR}/src/ocre/api/ocre_api.c ${OCRE_ROOT_DIR}/src/ocre/api/ocre_common.c diff --git a/src/shared/platform/zephyr/core_eventq.c b/src/shared/platform/zephyr/core_eventq.c new file mode 100644 index 00000000..7ec83f7a --- /dev/null +++ b/src/shared/platform/zephyr/core_eventq.c @@ -0,0 +1,64 @@ +/** + * @copyright Copyright © contributors to Project Ocre, + * which has been established as Project Ocre a Series of LF Projects, LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ocre_core_external.h" +#include +#include + +int core_eventq_init(core_eventq_t *eventq, size_t item_size, size_t max_items) { + eventq->buffer = core_malloc(item_size * max_items); + if (!eventq->buffer) { + return -ENOMEM; + } + eventq->item_size = item_size; + eventq->max_items = max_items; + + k_msgq_init(&eventq->msgq, (char *)eventq->buffer, item_size, max_items); + return 0; +} + +int core_eventq_peek(core_eventq_t *eventq, void *event) { + int ret = k_msgq_peek(&eventq->msgq, event); + if (ret == 0) { + return 0; + } else if (ret == -ENOMSG) { + return -ENOMSG; + } else { + return ret; + } +} + +int core_eventq_get(core_eventq_t *eventq, void *event) { + int ret = k_msgq_get(&eventq->msgq, event, K_NO_WAIT); + if (ret == 0) { + return 0; + } else if (ret == -ENOMSG) { + return -ENOENT; + } else { + return ret; + } +} + +int core_eventq_put(core_eventq_t *eventq, const void *event) { + int ret = k_msgq_put(&eventq->msgq, event, K_NO_WAIT); + if (ret == 0) { + return 0; + } else if (ret == -ENOMSG) { + return -ENOMEM; + } else { + return ret; + } +} + +void core_eventq_destroy(core_eventq_t *eventq) { + if (eventq->buffer) { + core_free(eventq->buffer); + eventq->buffer = NULL; + } +} + + diff --git a/src/shared/platform/zephyr/core_internal.h b/src/shared/platform/zephyr/core_internal.h index c148841c..26e0f971 100644 --- a/src/shared/platform/zephyr/core_internal.h +++ b/src/shared/platform/zephyr/core_internal.h @@ -193,4 +193,17 @@ typedef struct k_spinlock core_spinlock_t; */ typedef k_spinlock_key_t core_spinlock_key_t; +/** + * @brief Generic event queue structure for Zephyr platform. + * + * A thread-safe message queue implementation using Zephyr's k_msgq + * that can store any type of data items with configurable size and capacity. + */ +typedef struct { + void *buffer; /*!< Dynamically allocated buffer for queue items */ + size_t item_size; /*!< Size of each individual item in bytes */ + size_t max_items; /*!< Maximum number of items the queue can hold */ + struct k_msgq msgq; /*!< Zephyr message queue */ +} core_eventq_t; + #endif diff --git a/src/shared/platform/zephyr/ocre_internal.cmake b/src/shared/platform/zephyr/ocre_internal.cmake index 5e67c1d4..67e68393 100644 --- a/src/shared/platform/zephyr/ocre_internal.cmake +++ b/src/shared/platform/zephyr/ocre_internal.cmake @@ -78,6 +78,7 @@ set(lib_sources ${OCRE_ROOT_DIR}/src/shared/platform/zephyr/core_thread.c ${OCRE_ROOT_DIR}/src/shared/platform/zephyr/core_mutex.c ${OCRE_ROOT_DIR}/src/shared/platform/zephyr/core_mq.c + ${OCRE_ROOT_DIR}/src/shared/platform/zephyr/core_eventq.c ${OCRE_ROOT_DIR}/src/shared/platform/zephyr/core_misc.c ${OCRE_ROOT_DIR}/src/shared/platform/zephyr/core_memory.c ${OCRE_ROOT_DIR}/src/shared/platform/zephyr/core_timer.c From 2fe3ff83b9cf3ef74eb98388705ac9abab45d8e7 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:57:05 +0200 Subject: [PATCH 14/26] Move messaging back to its own module Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_api.c | 3 +- src/ocre/api/ocre_common.c | 262 +---------------- src/ocre/api/ocre_common.h | 48 --- .../container_supervisor/cs_sm_impl.c | 3 +- src/ocre/ocre_messaging/ocre_messaging.c | 277 ++++++++++-------- src/ocre/ocre_messaging/ocre_messaging.h | 54 ++-- src/shared/platform/posix/core_internal.h | 1 + src/shared/platform/posix/ocre_internal.cmake | 1 + .../platform/zephyr/ocre_internal.cmake | 3 +- 9 files changed, 187 insertions(+), 465 deletions(-) diff --git a/src/ocre/api/ocre_api.c b/src/ocre/api/ocre_api.c index b64a838e..f9f9d8db 100644 --- a/src/ocre/api/ocre_api.c +++ b/src/ocre/api/ocre_api.c @@ -40,8 +40,7 @@ #endif #ifdef CONFIG_OCRE_CONTAINER_MESSAGING -/* Messaging functionality is now integrated into ocre_common.c */ -/* #include "../ocre_messaging/ocre_messaging.h" */ +#include "../ocre_messaging/ocre_messaging.h" #endif int _ocre_posix_uname(wasm_exec_env_t exec_env, struct _ocre_posix_utsname *name) { diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 77c3ba38..d4d94fa5 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -19,7 +19,10 @@ LOG_MODULE_REGISTER(ocre_common, LOG_LEVEL_DBG); #ifdef __ZEPHYR__ #include "../ocre_gpio/ocre_gpio.h" /* Messaging functionality is now integrated into this file */ -/* #include "../ocre_messaging/ocre_messaging.h" */ +#endif + +#ifdef CONFIG_OCRE_CONTAINER_MESSAGING +#include "../ocre_messaging/ocre_messaging.h" #endif #include "ocre_common.h" @@ -749,260 +752,3 @@ static void posix_send_timer_event(int timer_id) { } #endif - -/* ========== OCRE MESSAGING FUNCTIONALITY ========== */ - -#ifndef CONFIG_MESSAGING_MAX_SUBSCRIPTIONS -#define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 32 -#endif -#define OCRE_MAX_TOPIC_LEN 64 - -/* Messaging subscription structure */ -typedef struct { - char topic[OCRE_MAX_TOPIC_LEN]; - wasm_module_inst_t module_inst; - bool is_active; -} ocre_messaging_subscription_t; - -typedef struct { - ocre_messaging_subscription_t subscriptions[CONFIG_MESSAGING_MAX_SUBSCRIPTIONS]; - uint16_t subscription_count; - core_mutex_t mutex; -} ocre_messaging_system_t; - -static ocre_messaging_system_t messaging_system = {0}; -static bool messaging_system_initialized = false; - -/* Initialize messaging system */ -int ocre_messaging_init(void) { - if (messaging_system_initialized) { - LOG_INF("Messaging system already initialized"); - return 0; - } - - memset(&messaging_system, 0, sizeof(ocre_messaging_system_t)); - - core_mutex_init(&messaging_system.mutex); - - ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_MESSAGING, ocre_messaging_cleanup_container); - messaging_system_initialized = true; - LOG_INF("Messaging system initialized"); - return 0; -} - -/* Cleanup messaging resources for a module */ -void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { - if (!messaging_system_initialized || !module_inst) { - return; - } - - core_mutex_lock(&messaging_system.mutex); - - for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { - if (messaging_system.subscriptions[i].is_active && - messaging_system.subscriptions[i].module_inst == module_inst) { - messaging_system.subscriptions[i].is_active = false; - messaging_system.subscriptions[i].module_inst = NULL; - messaging_system.subscriptions[i].topic[0] = '\0'; - messaging_system.subscription_count--; - ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); - LOG_INF("Cleaned up subscription %d for module %p", i, (void *)module_inst); - } - } - - core_mutex_unlock(&messaging_system.mutex); - - LOG_INF("Cleaned up messaging resources for module %p", (void *)module_inst); -} - -/* Subscribe to a topic */ -int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { - if (!messaging_system_initialized) { - if (ocre_messaging_init() != 0) { - LOG_ERR("Failed to initialize messaging system"); - return -EINVAL; - } - } - - if (!topic || ((char *)topic)[0] == '\0') { - LOG_ERR("Topic is NULL or empty"); - return -EINVAL; - } - - wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); - if (!module_inst) { - LOG_ERR("No module instance for exec_env"); - return -EINVAL; - } - - ocre_module_context_t *ctx = ocre_get_module_context(module_inst); - if (!ctx) { - LOG_ERR("Module context not found for module instance %p", (void *)module_inst); - return -EINVAL; - } - - core_mutex_lock(&messaging_system.mutex); - - // Check if already subscribed - for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { - if (messaging_system.subscriptions[i].is_active && - messaging_system.subscriptions[i].module_inst == module_inst && - strcmp(messaging_system.subscriptions[i].topic, (char *)topic) == 0) { - LOG_INF("Already subscribed to topic: %s", (char *)topic); - core_mutex_unlock(&messaging_system.mutex); - return 0; - } - } - - // Find a free slot - for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { - if (!messaging_system.subscriptions[i].is_active) { - strncpy(messaging_system.subscriptions[i].topic, (char *)topic, OCRE_MAX_TOPIC_LEN - 1); - messaging_system.subscriptions[i].topic[OCRE_MAX_TOPIC_LEN - 1] = '\0'; - messaging_system.subscriptions[i].module_inst = module_inst; - messaging_system.subscriptions[i].is_active = true; - messaging_system.subscription_count++; - ocre_increment_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); - LOG_INF("Subscribed to topic: %s, module: %p", (char *)topic, (void *)module_inst); - core_mutex_unlock(&messaging_system.mutex); - return 0; - } - } - - core_mutex_unlock(&messaging_system.mutex); - - LOG_ERR("No free subscription slots available"); - return -ENOMEM; -} - -/* Publish a message */ -int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len) { - if (!messaging_system_initialized) { - if (ocre_messaging_init() != 0) { - LOG_ERR("Failed to initialize messaging system"); - return -EINVAL; - } - } - - if (!topic || ((char *)topic)[0] == '\0') { - LOG_ERR("Topic is NULL or empty"); - return -EINVAL; - } - if (!content_type || ((char *)content_type)[0] == '\0') { - LOG_ERR("Content type is NULL or empty"); - return -EINVAL; - } - if (!payload || payload_len <= 0) { - LOG_ERR("Payload is NULL or payload_len is invalid"); - return -EINVAL; - } - - wasm_module_inst_t publisher_module = wasm_runtime_get_module_inst(exec_env); - if (!publisher_module) { - LOG_ERR("No module instance for exec_env"); - return -EINVAL; - } - - static uint32_t message_id = 0; - bool message_sent = false; - - core_mutex_lock(&messaging_system.mutex); - - // Find matching subscriptions - for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { - if (!messaging_system.subscriptions[i].is_active) { - continue; - } - - // Check if the published topic matches the subscription (prefix match) - const char *subscribed_topic = messaging_system.subscriptions[i].topic; - size_t subscribed_len = strlen(subscribed_topic); - - if (strncmp(subscribed_topic, (char *)topic, subscribed_len) != 0) { - continue; // No prefix match - } - - wasm_module_inst_t target_module = messaging_system.subscriptions[i].module_inst; - if (!target_module) { - LOG_ERR("Invalid module instance for subscription %d", i); - continue; - } - - // Allocate WASM memory for the target module - uint32_t topic_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)topic, strlen((char *)topic) + 1); - if (topic_offset == 0) { - LOG_ERR("Failed to allocate WASM memory for topic"); - continue; - } - - uint32_t content_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)content_type, strlen((char *)content_type) + 1); - if (content_offset == 0) { - LOG_ERR("Failed to allocate WASM memory for content_type"); - wasm_runtime_module_free(target_module, topic_offset); - continue; - } - - uint32_t payload_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, payload, payload_len); - if (payload_offset == 0) { - LOG_ERR("Failed to allocate WASM memory for payload"); - wasm_runtime_module_free(target_module, topic_offset); - wasm_runtime_module_free(target_module, content_offset); - continue; - } - - // Create and queue the messaging event - ocre_event_t event; - event.type = OCRE_RESOURCE_TYPE_MESSAGING; - event.data.messaging_event.message_id = message_id; - event.data.messaging_event.topic = topic; - event.data.messaging_event.topic_offset = topic_offset; - event.data.messaging_event.content_type = content_type; - event.data.messaging_event.content_type_offset = content_offset; - event.data.messaging_event.payload = payload; - event.data.messaging_event.payload_offset = payload_offset; - event.data.messaging_event.payload_len = (uint32_t)payload_len; - event.owner = target_module; - - LOG_DBG("Creating messaging event: ID=%d, topic=%s, content_type=%s, payload_len=%d for module %p", - message_id, (char *)topic, (char *)content_type, payload_len, (void *)target_module); - - core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - if (core_eventq_put(&ocre_event_queue, &event) != 0) { - LOG_ERR("Failed to queue messaging event for message ID %d", message_id); - wasm_runtime_module_free(target_module, topic_offset); - wasm_runtime_module_free(target_module, content_offset); - wasm_runtime_module_free(target_module, payload_offset); - } else { - message_sent = true; - LOG_DBG("Queued messaging event for message ID %d", message_id); - } - core_spinlock_unlock(&ocre_event_queue_lock, key); - } - - core_mutex_unlock(&messaging_system.mutex); - - if (message_sent) { - LOG_DBG("Published message: ID=%d, topic=%s, content_type=%s, payload_len=%d", - message_id, (char *)topic, (char *)content_type, payload_len); - message_id++; - return 0; - } else { - LOG_ERR("No matching subscriptions found for topic %s", (char *)topic); - return -ENOENT; - } -} - -/* Free module event data */ -int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, uint32_t payload_offset) { - wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); - if (!module_inst) { - LOG_ERR("Cannot find module_inst for free event data"); - return -EINVAL; - } - - wasm_runtime_module_free(module_inst, topic_offset); - wasm_runtime_module_free(module_inst, content_offset); - wasm_runtime_module_free(module_inst, payload_offset); - - return 0; -} diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index acffd5d5..ef7a64df 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -281,52 +281,4 @@ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id); */ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst); -/* ========== OCRE MESSAGING FUNCTIONALITY ========== */ - -/** - * @brief Initialize the messaging system. - * - * @return 0 on success, negative error code on failure. - */ -int ocre_messaging_init(void); - -/** - * @brief Subscribe to a topic. - * - * @param exec_env WASM execution environment. - * @param topic Topic to subscribe to. - * @return 0 on success, negative error code on failure. - */ -int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic); - -/** - * @brief Publish a message to a topic. - * - * @param exec_env WASM execution environment. - * @param topic Topic to publish to. - * @param content_type Content type of the message. - * @param payload Message payload. - * @param payload_len Length of the payload. - * @return 0 on success, negative error code on failure. - */ -int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len); - -/** - * @brief Free module event data. - * - * @param exec_env WASM execution environment. - * @param topic_offset Topic offset in WASM memory. - * @param content_offset Content type offset in WASM memory. - * @param payload_offset Payload offset in WASM memory. - * @return 0 on success, negative error code on failure. - */ -int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, uint32_t payload_offset); - -/** - * @brief Cleanup messaging resources for a module. - * - * @param module_inst WASM module instance. - */ -void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst); - #endif /* OCRE_COMMON_H */ diff --git a/src/ocre/components/container_supervisor/cs_sm_impl.c b/src/ocre/components/container_supervisor/cs_sm_impl.c index fa7f4a66..9ba3aafa 100644 --- a/src/ocre/components/container_supervisor/cs_sm_impl.c +++ b/src/ocre/components/container_supervisor/cs_sm_impl.c @@ -15,8 +15,7 @@ #include "ocre_gpio/ocre_gpio.h" #endif #ifdef CONFIG_OCRE_CONTAINER_MESSAGING -/* Messaging functionality is now integrated into ocre_common.c */ -/* #include "ocre_messaging/ocre_messaging.h" */ +#include "ocre_messaging/ocre_messaging.h" #endif #if defined(CONFIG_OCRE_TIMER) || defined(CONFIG_OCRE_GPIO) || defined(CONFIG_OCRE_SENSORS) || \ defined(CONFIG_OCRE_CONTAINER_MESSAGING) diff --git a/src/ocre/ocre_messaging/ocre_messaging.c b/src/ocre/ocre_messaging/ocre_messaging.c index c97da479..f6455d7f 100644 --- a/src/ocre/ocre_messaging/ocre_messaging.c +++ b/src/ocre/ocre_messaging/ocre_messaging.c @@ -6,55 +6,147 @@ */ #include +#include "ocre_core_external.h" #include #include -#include -#include -#include #include LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); -#define MESSAGING_MAX_SUBSCRIPTIONS CONFIG_MESSAGING_MAX_SUBSCRIPTIONS +/* ========== OCRE MESSAGING FUNCTIONALITY ========== */ -// Structure to hold the subscription information +#ifndef CONFIG_MESSAGING_MAX_SUBSCRIPTIONS +#define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 32 +#endif +#define OCRE_MAX_TOPIC_LEN 64 + +/* Messaging subscription structure */ typedef struct { - void *topic; // Topic pointer + char topic[OCRE_MAX_TOPIC_LEN]; wasm_module_inst_t module_inst; bool is_active; -} messaging_subscription_t; +} ocre_messaging_subscription_t; typedef struct { - messaging_subscription_t info[MESSAGING_MAX_SUBSCRIPTIONS]; - uint16_t subscriptions_number; -} messaging_subscription_list; + ocre_messaging_subscription_t subscriptions[CONFIG_MESSAGING_MAX_SUBSCRIPTIONS]; + uint16_t subscription_count; + core_mutex_t mutex; +} ocre_messaging_system_t; -static messaging_subscription_list subscription_list = {0}; +static ocre_messaging_system_t messaging_system = {0}; static bool messaging_system_initialized = false; +/* Initialize messaging system */ int ocre_messaging_init(void) { if (messaging_system_initialized) { LOG_INF("Messaging system already initialized"); - return -1; - } - if (!common_initialized && ocre_common_init() != 0) { - LOG_ERR("Failed to initialize common subsystem"); - return -2; + return 0; } - - memset(&subscription_list, 0, sizeof(messaging_subscription_list)); + + memset(&messaging_system, 0, sizeof(ocre_messaging_system_t)); + + core_mutex_init(&messaging_system.mutex); + ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_MESSAGING, ocre_messaging_cleanup_container); messaging_system_initialized = true; - LOG_INF("Messaging system initialized"); return 0; } -int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len) { +/* Cleanup messaging resources for a module */ +void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { + if (!messaging_system_initialized || !module_inst) { + return; + } + + core_mutex_lock(&messaging_system.mutex); + + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (messaging_system.subscriptions[i].is_active && + messaging_system.subscriptions[i].module_inst == module_inst) { + messaging_system.subscriptions[i].is_active = false; + messaging_system.subscriptions[i].module_inst = NULL; + messaging_system.subscriptions[i].topic[0] = '\0'; + messaging_system.subscription_count--; + ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); + LOG_INF("Cleaned up subscription %d for module %p", i, (void *)module_inst); + } + } + + core_mutex_unlock(&messaging_system.mutex); + + LOG_INF("Cleaned up messaging resources for module %p", (void *)module_inst); +} + +/* Subscribe to a topic */ +int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { if (!messaging_system_initialized) { - LOG_ERR("Messaging system not initialized"); + if (ocre_messaging_init() != 0) { + LOG_ERR("Failed to initialize messaging system"); + return -EINVAL; + } + } + + if (!topic || ((char *)topic)[0] == '\0') { + LOG_ERR("Topic is NULL or empty"); return -EINVAL; } + + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + if (!module_inst) { + LOG_ERR("No module instance for exec_env"); + return -EINVAL; + } + + ocre_module_context_t *ctx = ocre_get_module_context(module_inst); + if (!ctx) { + LOG_ERR("Module context not found for module instance %p", (void *)module_inst); + return -EINVAL; + } + + core_mutex_lock(&messaging_system.mutex); + + // Check if already subscribed + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (messaging_system.subscriptions[i].is_active && + messaging_system.subscriptions[i].module_inst == module_inst && + strcmp(messaging_system.subscriptions[i].topic, (char *)topic) == 0) { + LOG_INF("Already subscribed to topic: %s", (char *)topic); + core_mutex_unlock(&messaging_system.mutex); + return 0; + } + } + + // Find a free slot + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (!messaging_system.subscriptions[i].is_active) { + strncpy(messaging_system.subscriptions[i].topic, (char *)topic, OCRE_MAX_TOPIC_LEN - 1); + messaging_system.subscriptions[i].topic[OCRE_MAX_TOPIC_LEN - 1] = '\0'; + messaging_system.subscriptions[i].module_inst = module_inst; + messaging_system.subscriptions[i].is_active = true; + messaging_system.subscription_count++; + ocre_increment_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); + LOG_INF("Subscribed to topic: %s, module: %p", (char *)topic, (void *)module_inst); + core_mutex_unlock(&messaging_system.mutex); + return 0; + } + } + + core_mutex_unlock(&messaging_system.mutex); + + LOG_ERR("No free subscription slots available"); + return -ENOMEM; +} + +/* Publish a message */ +int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len) { + if (!messaging_system_initialized) { + if (ocre_messaging_init() != 0) { + LOG_ERR("Failed to initialize messaging system"); + return -EINVAL; + } + } + if (!topic || ((char *)topic)[0] == '\0') { LOG_ERR("Topic is NULL or empty"); return -EINVAL; @@ -67,52 +159,52 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ LOG_ERR("Payload is NULL or payload_len is invalid"); return -EINVAL; } - - if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { - LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); - return -EPIPE; - } - wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); - if (!module_inst) { + + wasm_module_inst_t publisher_module = wasm_runtime_get_module_inst(exec_env); + if (!publisher_module) { LOG_ERR("No module instance for exec_env"); return -EINVAL; } + static uint32_t message_id = 0; - bool posted = false; - - // Iterate through subscriptions to find matching topics - for (int i = 0; i < MESSAGING_MAX_SUBSCRIPTIONS; i++) { - if (!subscription_list.info[i].is_active) { + bool message_sent = false; + + core_mutex_lock(&messaging_system.mutex); + + // Find matching subscriptions + for (int i = 0; i < CONFIG_MESSAGING_MAX_SUBSCRIPTIONS; i++) { + if (!messaging_system.subscriptions[i].is_active) { continue; } - - char *subscribed_topic = (char *)subscription_list.info[i].topic; + + // Check if the published topic matches the subscription (prefix match) + const char *subscribed_topic = messaging_system.subscriptions[i].topic; size_t subscribed_len = strlen(subscribed_topic); - + if (strncmp(subscribed_topic, (char *)topic, subscribed_len) != 0) { continue; // No prefix match } - - wasm_module_inst_t target_module = subscription_list.info[i].module_inst; + + wasm_module_inst_t target_module = messaging_system.subscriptions[i].module_inst; if (!target_module) { LOG_ERR("Invalid module instance for subscription %d", i); continue; } - - // Allocate WASM memory for topic, content_type, and payload - uint32_t topic_offset = - (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)topic, strlen((char *)topic) + 1); + + // Allocate WASM memory for the target module + uint32_t topic_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)topic, strlen((char *)topic) + 1); if (topic_offset == 0) { LOG_ERR("Failed to allocate WASM memory for topic"); continue; } - uint32_t content_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)content_type, - strlen((char *)content_type) + 1); + + uint32_t content_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, (char *)content_type, strlen((char *)content_type) + 1); if (content_offset == 0) { LOG_ERR("Failed to allocate WASM memory for content_type"); wasm_runtime_module_free(target_module, topic_offset); continue; } + uint32_t payload_offset = (uint32_t)wasm_runtime_module_dup_data(target_module, payload, payload_len); if (payload_offset == 0) { LOG_ERR("Failed to allocate WASM memory for payload"); @@ -120,7 +212,8 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ wasm_runtime_module_free(target_module, content_offset); continue; } - + + // Create and queue the messaging event ocre_event_t event; event.type = OCRE_RESOURCE_TYPE_MESSAGING; event.data.messaging_event.message_id = message_id; @@ -132,23 +225,28 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ event.data.messaging_event.payload_offset = payload_offset; event.data.messaging_event.payload_len = (uint32_t)payload_len; event.owner = target_module; + + LOG_DBG("Creating messaging event: ID=%d, topic=%s, content_type=%s, payload_len=%d for module %p", + message_id, (char *)topic, (char *)content_type, payload_len, (void *)target_module); - k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); - if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); + if (core_eventq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue messaging event for message ID %d", message_id); wasm_runtime_module_free(target_module, topic_offset); wasm_runtime_module_free(target_module, content_offset); wasm_runtime_module_free(target_module, payload_offset); } else { - posted = true; - LOG_DBG("Queued messaging event: ID=%d, topic=%s, content_type=%s, payload_len=%d for module %p", - message_id, (char *)topic, (char *)content_type, payload_len, (void *)target_module); + message_sent = true; + LOG_DBG("Queued messaging event for message ID %d", message_id); } - k_spin_unlock(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); } - if (posted) { - LOG_DBG("Published message: ID=%d, topic=%s, content_type=%s, payload_len=%d", message_id, (char *)topic, - (char *)content_type, payload_len); + + core_mutex_unlock(&messaging_system.mutex); + + if (message_sent) { + LOG_DBG("Published message: ID=%d, topic=%s, content_type=%s, payload_len=%d", + message_id, (char *)topic, (char *)content_type, payload_len); message_id++; return 0; } else { @@ -157,75 +255,8 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ } } -int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic) { - if (!messaging_system_initialized) { - LOG_ERR("Messaging system not initialized"); - return -EINVAL; - } - if (subscription_list.subscriptions_number >= MESSAGING_MAX_SUBSCRIPTIONS) { - LOG_ERR("Maximum subscriptions reached"); - return -ENOMEM; - } - if (!topic || ((char *)topic)[0] == '\0') { - LOG_ERR("Topic is NULL or empty"); - return -EINVAL; - } - wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); - if (!module_inst) { - LOG_ERR("No module instance for exec_env"); - return -EINVAL; - } - ocre_module_context_t *ctx = ocre_get_module_context(module_inst); - if (!ctx || !ctx->exec_env) { - LOG_ERR("Execution environment not found for module instance %p", (void *)module_inst); - return -EINVAL; - } - - // Find a free slot for subscription - for (int i = 0; i < MESSAGING_MAX_SUBSCRIPTIONS; i++) { - if (!subscription_list.info[i].is_active) { - size_t topic_len = strlen((char *)topic) + 1; - subscription_list.info[i].topic = k_malloc(topic_len); - if (!subscription_list.info[i].topic) { - LOG_ERR("Failed to allocate memory for topic"); - return -ENOMEM; - } - - strcpy((char *)subscription_list.info[i].topic, (char *)topic); - subscription_list.info[i].module_inst = module_inst; - subscription_list.info[i].is_active = true; - subscription_list.subscriptions_number++; - ocre_increment_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); - LOG_INF("Subscribed to topic: %s, current module_inst: %p", (char *)topic, (void *)module_inst); - return 0; - } - } - LOG_ERR("No free subscription slots available"); - return -ENOMEM; -} - -void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { - if (!messaging_system_initialized || !module_inst) { - LOG_ERR("Messaging system not initialized or invalid module %p", (void *)module_inst); - return; - } - // Clean up subscriptions - for (int i = 0; i < MESSAGING_MAX_SUBSCRIPTIONS; i++) { - if (subscription_list.info[i].is_active && subscription_list.info[i].module_inst == module_inst) { - k_free(subscription_list.info[i].topic); - subscription_list.info[i].topic = NULL; - subscription_list.info[i].module_inst = NULL; - subscription_list.info[i].is_active = false; - subscription_list.subscriptions_number--; - ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); - LOG_INF("Cleaned up subscription %d for module %p", i, (void *)module_inst); - } - } - LOG_INF("Cleaned up messaging resources for module %p", (void *)module_inst); -} - -int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, - uint32_t payload_offset) { +/* Free module event data */ +int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, uint32_t payload_offset) { wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); if (!module_inst) { LOG_ERR("Cannot find module_inst for free event data"); diff --git a/src/ocre/ocre_messaging/ocre_messaging.h b/src/ocre/ocre_messaging/ocre_messaging.h index bdbf3ea9..eaa2ebdf 100644 --- a/src/ocre/ocre_messaging/ocre_messaging.h +++ b/src/ocre/ocre_messaging/ocre_messaging.h @@ -9,9 +9,7 @@ #define OCRE_MESSAGING_H #include -#include -#include -#include +#include "ocre_core_external.h" #include #define MESSAGING_QUEUE_SIZE 100 @@ -28,53 +26,49 @@ typedef struct { } ocre_msg_t; /** - * @brief Initialize the OCRE messaging system. + * @brief Initialize the messaging system. + * + * @return 0 on success, negative error code on failure. */ int ocre_messaging_init(void); /** - * @brief Publish a message to the specified topic. + * @brief Subscribe to a topic. * * @param exec_env WASM execution environment. - * @param topic The name of the topic to publish to (pointer). - * @param content_type The content type of the message (e.g., MIME type, pointer). - * @param payload The message payload. - * @param payload_len The length of the payload. + * @param topic Topic to subscribe to. * @return 0 on success, negative error code on failure. */ -int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len); +int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic); /** - * @brief Subscribe to messages on a specified topic. + * @brief Publish a message to a topic. * * @param exec_env WASM execution environment. - * @param topic The name of the topic to subscribe to (pointer). + * @param topic Topic to publish to. + * @param content_type Content type of the message. + * @param payload Message payload. + * @param payload_len Length of the payload. * @return 0 on success, negative error code on failure. */ -int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic); +int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len); /** - * @brief Clean up messaging resources for a WASM module. + * @brief Free module event data. * - * @param module_inst The WASM module instance to clean up. + * @param exec_env WASM execution environment. + * @param topic_offset Topic offset in WASM memory. + * @param content_offset Content type offset in WASM memory. + * @param payload_offset Payload offset in WASM memory. + * @return 0 on success, negative error code on failure. */ -void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst); +int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, uint32_t payload_offset); /** - * @brief Frees allocated memory for a messaging event in the WASM module. + * @brief Cleanup messaging resources for a module. * - * This function releases the allocated memory for the topic, content-type, and payload - * associated with a messaging event received by the WASM module. It should be called - * after processing the message to prevent memory leaks. - * - * @param exec_env WASM execution environment. - * @param topic_offset Offset in WASM memory for the message topic. - * @param content_offset Offset in WASM memory for the message content-type. - * @param payload_offset Offset in WASM memory for the message payload. - * - * @return OCRE_SUCCESS on success, negative error code on failure. + * @param module_inst WASM module instance. */ -int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, - uint32_t payload_offset); +void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst); -#endif /* OCRE_MESSAGING_H */ \ No newline at end of file +#endif /* OCRE_MESSAGING_H */ diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index 48a5eb25..15a62bc3 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -15,6 +15,7 @@ #include #include #include +#include #include diff --git a/src/shared/platform/posix/ocre_internal.cmake b/src/shared/platform/posix/ocre_internal.cmake index 5bdcaaaa..a4056e74 100644 --- a/src/shared/platform/posix/ocre_internal.cmake +++ b/src/shared/platform/posix/ocre_internal.cmake @@ -84,6 +84,7 @@ set(lib_sources ${OCRE_ROOT_DIR}/src/ocre/api/ocre_common.c # Timer functionality is now integrated into ocre_common.c # ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c + ${OCRE_ROOT_DIR}/src/ocre/ocre_messaging/ocre_messaging.c # Utils ${OCRE_ROOT_DIR}/src/ocre/utils/strlcat.c ) diff --git a/src/shared/platform/zephyr/ocre_internal.cmake b/src/shared/platform/zephyr/ocre_internal.cmake index 67e68393..c6d45c51 100644 --- a/src/shared/platform/zephyr/ocre_internal.cmake +++ b/src/shared/platform/zephyr/ocre_internal.cmake @@ -107,8 +107,7 @@ if(DEFINED CONFIG_OCRE_GPIO) endif() if(CONFIG_OCRE_CONTAINER_MESSAGING) - # Messaging functionality is now integrated into ocre_common.c - # list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_messaging/ocre_messaging.c) + list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_messaging/ocre_messaging.c) endif() # Add all sources to the app target at once From 596f9e57dc6c9ae3408f151319505babd6d5400f Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:13:26 +0200 Subject: [PATCH 15/26] Move back timers to their own module Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_api.c | 7 +- src/ocre/api/ocre_common.c | 353 +----------------- src/ocre/api/ocre_common.h | 66 ---- .../container_supervisor/cs_sm_impl.c | 7 +- src/ocre/ocre_timers/ocre_timer.c | 81 ++-- src/ocre/ocre_timers/ocre_timer.h | 77 ++-- src/shared/platform/posix/ocre_internal.cmake | 3 +- .../platform/zephyr/ocre_internal.cmake | 7 +- 8 files changed, 81 insertions(+), 520 deletions(-) diff --git a/src/ocre/api/ocre_api.c b/src/ocre/api/ocre_api.c index f9f9d8db..b6aa95de 100644 --- a/src/ocre/api/ocre_api.c +++ b/src/ocre/api/ocre_api.c @@ -20,10 +20,9 @@ #include "ocre_api.h" -// Timer functionality is now integrated into ocre_common.c -// #ifdef CONFIG_OCRE_TIMER -// #include "../ocre_timers/ocre_timer.h" -// #endif +#ifdef CONFIG_OCRE_TIMER +#include "../ocre_timers/ocre_timer.h" +#endif #include "ocre/utils/utils.h" diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index d4d94fa5..2854a3e7 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -16,13 +16,13 @@ LOG_MODULE_REGISTER(ocre_common, LOG_LEVEL_DBG); -#ifdef __ZEPHYR__ +#ifdef CONFIG_OCRE_GPIO #include "../ocre_gpio/ocre_gpio.h" -/* Messaging functionality is now integrated into this file */ #endif #ifdef CONFIG_OCRE_CONTAINER_MESSAGING -#include "../ocre_messaging/ocre_messaging.h" +#include "../ocre_timers/ocre_timer.h" +#include "../ocre_messaging/ocre_messaging.h" #endif #include "ocre_common.h" @@ -405,350 +405,3 @@ void ocre_cleanup_module_resources(wasm_module_inst_t module_inst) { wasm_module_inst_t ocre_get_current_module(void) { return current_module_tls ? *current_module_tls : NULL; } - -/* ========== OCRE TIMER FUNCTIONALITY ========== */ - -#include "ocre_common.h" - -/* Timer type definition */ -typedef uint32_t ocre_timer_t; - -/* Platform-specific timer structures */ -#ifdef __ZEPHYR__ -// Compact timer structure for Zephyr -typedef struct { - uint32_t in_use: 1; - uint32_t id: 8; // Up to 256 timers - uint32_t interval: 16; // Up to 65s intervals - uint32_t periodic: 1; - struct k_timer timer; - wasm_module_inst_t owner; -} ocre_timer_internal; - -#else /* POSIX */ -// POSIX timer structure -typedef struct { - uint32_t in_use: 1; - uint32_t id: 8; // Up to 256 timers - uint32_t interval: 16; // Up to 65s intervals - uint32_t periodic: 1; - timer_t timer; - pthread_t thread; - bool thread_running; - wasm_module_inst_t owner; -} ocre_timer_internal; - -/* POSIX timer thread function - not used currently */ -#endif - -#ifndef CONFIG_MAX_TIMER -#define CONFIG_MAX_TIMERS 5 -#endif - -// Static data -static ocre_timer_internal timers[CONFIG_MAX_TIMERS]; -static bool timer_system_initialized = false; - -#ifdef __ZEPHYR__ -static void timer_callback_wrapper(struct k_timer *timer); -#else -static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc); -static void posix_send_timer_event(int timer_id); -#endif - -void ocre_timer_init(void) { - if (timer_system_initialized) { - LOG_INF("Timer system already initialized"); - return; - } - - if (!common_initialized && ocre_common_init() != 0) { - LOG_ERR("Failed to initialize common subsystem"); - return; - } - -#ifndef __ZEPHYR__ - // Setup POSIX signal handler for timer callbacks - struct sigaction sa; - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = posix_timer_signal_handler; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGALRM, &sa, NULL) == -1) { - LOG_ERR("Failed to setup POSIX timer signal handler"); - return; - } -#endif - - ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_TIMER, ocre_timer_cleanup_container); - timer_system_initialized = true; - LOG_INF("Timer system initialized"); -} - -int ocre_timer_create(wasm_exec_env_t exec_env, int id) { - wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); - if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { - LOG_ERR("Invalid module %p or timer ID %d (max: %d)", (void *)module, id, CONFIG_MAX_TIMERS); - return -EINVAL; - } - - ocre_timer_internal *timer = &timers[id - 1]; - if (timer->in_use) { - LOG_ERR("Timer ID %d already in use", id); - return -EBUSY; - } - - timer->id = id; - timer->owner = module; - timer->in_use = 1; - -#ifdef __ZEPHYR__ - k_timer_init(&timer->timer, timer_callback_wrapper, NULL); -#else - struct sigevent sev; - memset(&sev, 0, sizeof(sev)); - sev.sigev_notify = SIGEV_SIGNAL; - sev.sigev_signo = SIGALRM; - sev.sigev_value.sival_int = id; - - if (timer_create(CLOCK_REALTIME, &sev, &timer->timer) == -1) { - LOG_ERR("Failed to create POSIX timer %d", id); - timer->in_use = 0; - return -EINVAL; - } - timer->thread_running = false; -#endif - - ocre_increment_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); - LOG_INF("Created timer %d for module %p", id, (void *)module); - return 0; -} - -int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id) { - wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); - if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { - LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); - return -EINVAL; - } - - ocre_timer_internal *timer = &timers[id - 1]; - if (!timer->in_use || timer->owner != module) { - LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); - return -EINVAL; - } - -#ifdef __ZEPHYR__ - k_timer_stop(&timer->timer); -#else - timer_delete(timer->timer); - if (timer->thread_running) { - pthread_cancel(timer->thread); - timer->thread_running = false; - } -#endif - - timer->in_use = 0; - timer->owner = NULL; - ocre_decrement_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); - LOG_INF("Deleted timer %d", id); - return 0; -} - -int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, int is_periodic) { - wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); - if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { - LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); - return -EINVAL; - } - - ocre_timer_internal *timer = &timers[id - 1]; - if (!timer->in_use || timer->owner != module) { - LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); - return -EINVAL; - } - - if (interval <= 0 || interval > 65535) { - LOG_ERR("Invalid interval %dms (must be 1-65535ms)", interval); - return -EINVAL; - } - - timer->interval = interval; - timer->periodic = is_periodic; - -#ifdef __ZEPHYR__ - k_timeout_t duration = K_MSEC(interval); - k_timeout_t period = is_periodic ? duration : K_NO_WAIT; - k_timer_start(&timer->timer, duration, period); -#else - struct itimerspec its; - its.it_value.tv_sec = interval / 1000; - its.it_value.tv_nsec = (interval % 1000) * 1000000; - - if (is_periodic) { - its.it_interval.tv_sec = its.it_value.tv_sec; - its.it_interval.tv_nsec = its.it_value.tv_nsec; - } else { - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - } - - if (timer_settime(timer->timer, 0, &its, NULL) == -1) { - LOG_ERR("Failed to start POSIX timer %d", id); - return -EINVAL; - } -#endif - - LOG_INF("Started timer %d with interval %dms, periodic=%d", id, interval, is_periodic); - return 0; -} - -int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id) { - wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); - if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { - LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); - return -EINVAL; - } - - ocre_timer_internal *timer = &timers[id - 1]; - if (!timer->in_use || timer->owner != module) { - LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); - return -EINVAL; - } - -#ifdef __ZEPHYR__ - k_timer_stop(&timer->timer); -#else - struct itimerspec its; - memset(&its, 0, sizeof(its)); - timer_settime(timer->timer, 0, &its, NULL); -#endif - - LOG_INF("Stopped timer %d", id); - return 0; -} - -int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id) { - wasm_module_inst_t module = wasm_runtime_get_module_inst(exec_env); - if (!module || id <= 0 || id > CONFIG_MAX_TIMERS) { - LOG_ERR("Invalid module %p or timer ID %d", (void *)module, id); - return -EINVAL; - } - - ocre_timer_internal *timer = &timers[id - 1]; - if (!timer->in_use || timer->owner != module) { - LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); - return -EINVAL; - } - - int remaining; -#ifdef __ZEPHYR__ - remaining = k_ticks_to_ms_floor32(k_timer_remaining_ticks(&timer->timer)); -#else - struct itimerspec its; - if (timer_gettime(timer->timer, &its) == -1) { - LOG_ERR("Failed to get remaining time for timer %d", id); - return -EINVAL; - } - remaining = its.it_value.tv_sec * 1000 + its.it_value.tv_nsec / 1000000; -#endif - - LOG_INF("Timer %d remaining time: %dms", id, remaining); - return remaining; -} - -void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { - if (!module_inst) { - LOG_ERR("Invalid module instance for cleanup"); - return; - } - - for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { - if (timers[i].in_use && timers[i].owner == module_inst) { -#ifdef __ZEPHYR__ - k_timer_stop(&timers[i].timer); -#else - timer_delete(timers[i].timer); - if (timers[i].thread_running) { - pthread_cancel(timers[i].thread); - timers[i].thread_running = false; - } -#endif - timers[i].in_use = 0; - timers[i].owner = NULL; - ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_TIMER); - LOG_INF("Cleaned up timer %d for module %p", i + 1, (void *)module_inst); - } - } - LOG_INF("Cleaned up timer resources for module %p", (void *)module_inst); -} - -#ifdef __ZEPHYR__ -static void timer_callback_wrapper(struct k_timer *timer) { - if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { - LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); - return; - } - if (!timer) { - LOG_ERR("Null timer pointer in callback"); - return; - } - LOG_DBG("Timer callback for timer %p", (void *)timer); - LOG_DBG("ocre_event_queue at %p", (void *)&ocre_event_queue); - for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { - if (timers[i].in_use && &timers[i].timer == timer && timers[i].owner) { - ocre_event_t event; - event.type = OCRE_RESOURCE_TYPE_TIMER; - event.data.timer_event.timer_id = timers[i].id; - event.owner = timers[i].owner; - - LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, event.data.timer_event.timer_id, - (void *)timers[i].owner); - core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - if (core_eventq_put(&ocre_event_queue, &event) != 0) { - LOG_ERR("Failed to queue timer event for timer %d", timers[i].id); - } else { - LOG_DBG("Queued timer event for timer %d", timers[i].id); - } - core_spinlock_unlock(&ocre_event_queue_lock, key); - } - } -} - -#else /* POSIX */ - -static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc) { - (void)sig; - (void)uc; - if (si && si->si_value.sival_int > 0 && si->si_value.sival_int <= CONFIG_MAX_TIMERS) { - posix_send_timer_event(si->si_value.sival_int); - } -} - -static void posix_send_timer_event(int timer_id) { - if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { - LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); - return; - } - - int index = timer_id - 1; - if (index < 0 || index >= CONFIG_MAX_TIMERS || !timers[index].in_use) { - LOG_ERR("Invalid timer ID %d in callback", timer_id); - return; - } - - ocre_event_t event; - event.type = OCRE_RESOURCE_TYPE_TIMER; - event.data.timer_event.timer_id = timer_id; - event.owner = timers[index].owner; - - LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer_id, (void *)timers[index].owner); - - core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - if (core_eventq_put(&ocre_event_queue, &event) != 0) { - LOG_ERR("Failed to queue timer event for timer %d", timer_id); - } else { - LOG_DBG("Queued timer event for timer %d", timer_id); - } - core_spinlock_unlock(&ocre_event_queue_lock, key); -} - -#endif diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index ef7a64df..b614a56c 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -215,70 +215,4 @@ int ocre_get_event(wasm_exec_env_t exec_env, uint32_t type_offset, uint32_t id_o void ocre_common_shutdown(void); -/* ========== OCRE TIMER FUNCTIONALITY ========== */ - -#ifndef OCRE_TIMER_T_DEFINED -#define OCRE_TIMER_T_DEFINED -typedef uint32_t ocre_timer_t; -#endif - -/** - * @brief Initialize the timer system. - */ -void ocre_timer_init(void); - -/** - * @brief Create a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return 0 on success, negative error code on failure. - */ -int ocre_timer_create(wasm_exec_env_t exec_env, int id); - -/** - * @brief Delete a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return 0 on success, negative error code on failure. - */ -int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id); - -/** - * @brief Start a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @param interval Timer interval in milliseconds. - * @param is_periodic Whether the timer is periodic. - * @return 0 on success, negative error code on failure. - */ -int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, int is_periodic); - -/** - * @brief Stop a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return 0 on success, negative error code on failure. - */ -int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id); - -/** - * @brief Get remaining time for a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return Remaining time in milliseconds, or negative error code on failure. - */ -int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id); - -/** - * @brief Cleanup timer resources for a module. - * - * @param module_inst WASM module instance. - */ -void ocre_timer_cleanup_container(wasm_module_inst_t module_inst); - #endif /* OCRE_COMMON_H */ diff --git a/src/ocre/components/container_supervisor/cs_sm_impl.c b/src/ocre/components/container_supervisor/cs_sm_impl.c index 9ba3aafa..8b96f4a6 100644 --- a/src/ocre/components/container_supervisor/cs_sm_impl.c +++ b/src/ocre/components/container_supervisor/cs_sm_impl.c @@ -7,10 +7,9 @@ #include #include "ocre_core_external.h" -// Timer functionality is now integrated into ocre_common.c -// #ifdef CONFIG_OCRE_TIMER -// #include "ocre_timers/ocre_timer.h" -// #endif +#ifdef CONFIG_OCRE_TIMER +#include "ocre_timers/ocre_timer.h" +#endif #ifdef CONFIG_OCRE_GPIO #include "ocre_gpio/ocre_gpio.h" #endif diff --git a/src/ocre/ocre_timers/ocre_timer.c b/src/ocre/ocre_timers/ocre_timer.c index ca9a122b..0d49ae41 100644 --- a/src/ocre/ocre_timers/ocre_timer.c +++ b/src/ocre/ocre_timers/ocre_timer.c @@ -6,8 +6,8 @@ */ #include -#include #include +#include #include #include @@ -15,20 +15,13 @@ #include #include -#ifdef CONFIG_ZEPHYR -#include -#include -#include LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); -#else -#include -#include -#include -#include -#endif + +/* Timer type definition */ +typedef uint32_t ocre_timer_t; /* Platform-specific timer structures */ -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ // Compact timer structure for Zephyr typedef struct { uint32_t in_use: 1; @@ -37,7 +30,7 @@ typedef struct { uint32_t periodic: 1; struct k_timer timer; wasm_module_inst_t owner; -} ocre_timer; +} ocre_timer_internal; #else /* POSIX */ // POSIX timer structure @@ -50,10 +43,9 @@ typedef struct { pthread_t thread; bool thread_running; wasm_module_inst_t owner; -} ocre_timer; +} ocre_timer_internal; -/* POSIX timer thread function */ -static void* posix_timer_thread(void* arg); +/* POSIX timer thread function - not used currently */ #endif #ifndef CONFIG_MAX_TIMER @@ -61,10 +53,10 @@ static void* posix_timer_thread(void* arg); #endif // Static data -static ocre_timer timers[CONFIG_MAX_TIMERS]; +static ocre_timer_internal timers[CONFIG_MAX_TIMERS]; static bool timer_system_initialized = false; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ static void timer_callback_wrapper(struct k_timer *timer); #else static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc); @@ -82,7 +74,7 @@ void ocre_timer_init(void) { return; } -#ifndef CONFIG_ZEPHYR +#ifndef __ZEPHYR__ // Setup POSIX signal handler for timer callbacks struct sigaction sa; sa.sa_flags = SA_SIGINFO; @@ -106,7 +98,7 @@ int ocre_timer_create(wasm_exec_env_t exec_env, int id) { return -EINVAL; } - ocre_timer *timer = &timers[id - 1]; + ocre_timer_internal *timer = &timers[id - 1]; if (timer->in_use) { LOG_ERR("Timer ID %d already in use", id); return -EBUSY; @@ -116,7 +108,7 @@ int ocre_timer_create(wasm_exec_env_t exec_env, int id) { timer->owner = module; timer->in_use = 1; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_init(&timer->timer, timer_callback_wrapper, NULL); #else struct sigevent sev; @@ -145,16 +137,16 @@ int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id) { return -EINVAL; } - ocre_timer *timer = &timers[id - 1]; + ocre_timer_internal *timer = &timers[id - 1]; if (!timer->in_use || timer->owner != module) { LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); return -EINVAL; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_stop(&timer->timer); #else - timer_delete(&timer->timer); + timer_delete(timer->timer); if (timer->thread_running) { pthread_cancel(timer->thread); timer->thread_running = false; @@ -175,7 +167,7 @@ int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, in return -EINVAL; } - ocre_timer *timer = &timers[id - 1]; + ocre_timer_internal *timer = &timers[id - 1]; if (!timer->in_use || timer->owner != module) { LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); return -EINVAL; @@ -189,7 +181,7 @@ int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, in timer->interval = interval; timer->periodic = is_periodic; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timeout_t duration = K_MSEC(interval); k_timeout_t period = is_periodic ? duration : K_NO_WAIT; k_timer_start(&timer->timer, duration, period); @@ -223,13 +215,13 @@ int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id) { return -EINVAL; } - ocre_timer *timer = &timers[id - 1]; + ocre_timer_internal *timer = &timers[id - 1]; if (!timer->in_use || timer->owner != module) { LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); return -EINVAL; } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_stop(&timer->timer); #else struct itimerspec its; @@ -248,14 +240,14 @@ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id) { return -EINVAL; } - ocre_timer *timer = &timers[id - 1]; + ocre_timer_internal *timer = &timers[id - 1]; if (!timer->in_use || timer->owner != module) { LOG_ERR("Timer ID %d not in use or not owned by module %p", id, (void *)module); return -EINVAL; } int remaining; -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ remaining = k_ticks_to_ms_floor32(k_timer_remaining_ticks(&timer->timer)); #else struct itimerspec its; @@ -278,10 +270,10 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { if (timers[i].in_use && timers[i].owner == module_inst) { -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ k_timer_stop(&timers[i].timer); #else - timer_delete(&timers[i].timer); + timer_delete(timers[i].timer); if (timers[i].thread_running) { pthread_cancel(timers[i].thread); timers[i].thread_running = false; @@ -296,7 +288,7 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { LOG_INF("Cleaned up timer resources for module %p", (void *)module_inst); } -#ifdef CONFIG_ZEPHYR +#ifdef __ZEPHYR__ static void timer_callback_wrapper(struct k_timer *timer) { if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); @@ -306,12 +298,8 @@ static void timer_callback_wrapper(struct k_timer *timer) { LOG_ERR("Null timer pointer in callback"); return; } - if ((uintptr_t)ocre_event_queue_buffer_ptr % 4 != 0) { - LOG_ERR("ocre_event_queue_buffer misaligned: %p", (void *)ocre_event_queue_buffer_ptr); - return; - } LOG_DBG("Timer callback for timer %p", (void *)timer); - LOG_DBG("ocre_event_queue at %p, buffer at %p", (void *)&ocre_event_queue, (void *)ocre_event_queue_buffer_ptr); + LOG_DBG("ocre_event_queue at %p", (void *)&ocre_event_queue); for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { if (timers[i].in_use && &timers[i].timer == timer && timers[i].owner) { ocre_event_t event; @@ -321,14 +309,13 @@ static void timer_callback_wrapper(struct k_timer *timer) { LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, event.data.timer_event.timer_id, (void *)timers[i].owner); - LOG_DBG("Event address: %p, Queue buffer: %p", (void *)&event, (void *)ocre_event_queue_buffer_ptr); - k_spinlock_key_t key = k_spin_lock(&ocre_event_queue_lock); - if (k_msgq_put(&ocre_event_queue, &event, K_NO_WAIT) != 0) { + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); + if (core_eventq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue timer event for timer %d", timers[i].id); } else { LOG_DBG("Queued timer event for timer %d", timers[i].id); } - k_spin_unlock(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); } } } @@ -362,17 +349,13 @@ static void posix_send_timer_event(int timer_id) { LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer_id, (void *)timers[index].owner); - // Use the POSIX message queue implementation - extern posix_msgq_t ocre_event_queue; - extern posix_spinlock_t ocre_event_queue_lock; - - posix_spinlock_key_t key = OCRE_SPINLOCK_LOCK(&ocre_event_queue_lock); - if (posix_msgq_put(&ocre_event_queue, &event) != 0) { + core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); + if (core_eventq_put(&ocre_event_queue, &event) != 0) { LOG_ERR("Failed to queue timer event for timer %d", timer_id); } else { LOG_DBG("Queued timer event for timer %d", timer_id); } - OCRE_SPINLOCK_UNLOCK(&ocre_event_queue_lock, key); + core_spinlock_unlock(&ocre_event_queue_lock, key); } #endif diff --git a/src/ocre/ocre_timers/ocre_timer.h b/src/ocre/ocre_timers/ocre_timer.h index 1cdf1289..a47194ed 100644 --- a/src/ocre/ocre_timers/ocre_timer.h +++ b/src/ocre/ocre_timers/ocre_timer.h @@ -11,73 +11,68 @@ #include #include "ocre_core_external.h" -typedef int ocre_timer_t; +#ifndef OCRE_TIMER_T_DEFINED +#define OCRE_TIMER_T_DEFINED +typedef uint32_t ocre_timer_t; +#endif /** - * @brief Timer callback function type - * @param timer_id ID of the expired timer + * @brief Initialize the timer system. */ -typedef void (*timer_dispatcher_t)(uint32_t timer_id); +void ocre_timer_init(void); /** - * @brief Creates a new timer instance - * @param exec_env WASM execution environment - * @param id Unique timer identifier (1-CONFIG_MAX_TIMERS) - * @return 0 on success, -1 on error with errno set - * @retval EINVAL Invalid ID or timer system not initialized - * @retval EEXIST Timer ID already in use + * @brief Create a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return 0 on success, negative error code on failure. */ int ocre_timer_create(wasm_exec_env_t exec_env, int id); /** - * @brief Deletes a timer instance - * @param exec_env WASM execution environment - * @param id Timer identifier to delete - * @return 0 on success, -1 on error with errno set - * @retval EINVAL Timer not found or not in use + * @brief Delete a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return 0 on success, negative error code on failure. */ int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id); /** - * @brief Starts a timer with specified parameters - * @param exec_env WASM execution environment - * @param id Timer identifier to start - * @param interval Initial expiration time in milliseconds - * @param is_periodic 1 for periodic timer, 0 for one-shot - * @return 0 on success, -1 on error with errno set - * @retval EINVAL Invalid timer ID or interval <= 0 + * @brief Start a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @param interval Timer interval in milliseconds. + * @param is_periodic Whether the timer is periodic. + * @return 0 on success, negative error code on failure. */ int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, int is_periodic); /** - * @brief Stops a running timer - * @param exec_env WASM execution environment - * @param id Timer identifier to stop - * @return 0 on success, -1 on error with errno set - * @retval EINVAL Timer not found or not in use + * @brief Stop a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return 0 on success, negative error code on failure. */ int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id); /** - * @brief Gets the remaining time for a timer - * @param exec_env WASM execution environment - * @param id Timer identifier - * @return Remaining time in milliseconds, or -1 on error with errno set - * @retval EINVAL Invalid timer ID or timer not found + * @brief Get remaining time for a timer. + * + * @param exec_env WASM execution environment. + * @param id Timer ID. + * @return Remaining time in milliseconds, or negative error code on failure. */ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id); /** - * @brief Cleans up all timers associated with a WASM module instance - * @param module_inst WASM module instance to clean up + * @brief Cleanup timer resources for a module. + * + * @param module_inst WASM module instance. */ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst); -/** - * @brief Initializes the timer subsystem - * @note Must be called once before any other timer operations - */ -void ocre_timer_init(void); - -int ocre_timer_set_callback(wasm_exec_env_t exec_env, const char *callback_name); #endif /* OCRE_TIMER_H */ diff --git a/src/shared/platform/posix/ocre_internal.cmake b/src/shared/platform/posix/ocre_internal.cmake index a4056e74..03ec062b 100644 --- a/src/shared/platform/posix/ocre_internal.cmake +++ b/src/shared/platform/posix/ocre_internal.cmake @@ -82,8 +82,7 @@ set(lib_sources # APIs ${OCRE_ROOT_DIR}/src/ocre/api/ocre_api.c ${OCRE_ROOT_DIR}/src/ocre/api/ocre_common.c - # Timer functionality is now integrated into ocre_common.c - # ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c + ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c ${OCRE_ROOT_DIR}/src/ocre/ocre_messaging/ocre_messaging.c # Utils ${OCRE_ROOT_DIR}/src/ocre/utils/strlcat.c diff --git a/src/shared/platform/zephyr/ocre_internal.cmake b/src/shared/platform/zephyr/ocre_internal.cmake index c6d45c51..38fbcd16 100644 --- a/src/shared/platform/zephyr/ocre_internal.cmake +++ b/src/shared/platform/zephyr/ocre_internal.cmake @@ -89,10 +89,9 @@ set(lib_sources ) # Conditionally add sources -# Timer functionality is now integrated into ocre_common.c -# if(CONFIG_OCRE_TIMER) -# list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c) -# endif() +if(CONFIG_OCRE_TIMER) + list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_timers/ocre_timer.c) +endif() if(CONFIG_OCRE_SENSORS) list(APPEND lib_sources ${OCRE_ROOT_DIR}/src/ocre/ocre_sensors/ocre_sensors.c) From b5bc13426b9a1af205420b49eb5cedbca088df35 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:17:47 +0200 Subject: [PATCH 16/26] remove preinit initialization Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 8 +------- src/ocre/ocre_messaging/ocre_messaging.c | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 2854a3e7..37be0d37 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -217,13 +217,7 @@ int ocre_common_init(void) { #endif initialized = true; common_initialized = true; - - /* Initialize timer system as part of common initialization */ - ocre_timer_init(); - - /* Initialize messaging system as part of common initialization */ - ocre_messaging_init(); - + LOG_INF("OCRE common initialized successfully"); return 0; } diff --git a/src/ocre/ocre_messaging/ocre_messaging.c b/src/ocre/ocre_messaging/ocre_messaging.c index f6455d7f..3709e8f5 100644 --- a/src/ocre/ocre_messaging/ocre_messaging.c +++ b/src/ocre/ocre_messaging/ocre_messaging.c @@ -13,8 +13,6 @@ LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); -/* ========== OCRE MESSAGING FUNCTIONALITY ========== */ - #ifndef CONFIG_MESSAGING_MAX_SUBSCRIPTIONS #define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 32 #endif From dce6602cabe41987bb2b49efa680ac630c3f7556 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:29:25 +0200 Subject: [PATCH 17/26] Cleanup messaging Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.h | 3 +- src/ocre/ocre_messaging/ocre_messaging.c | 2 +- src/ocre/ocre_messaging/ocre_messaging.h | 48 +++++++++++++----------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index b614a56c..0789093e 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -12,13 +12,12 @@ #include #include #include "ocre_core_external.h" +#include "../ocre_messaging/ocre_messaging.h" /* Platform-specific includes */ #ifdef __ZEPHYR__ #include #include -/* Messaging functionality is now integrated into ocre_common.c */ -/* #include "../ocre_messaging/ocre_messaging.h" */ #else #include /* Forward declarations for POSIX messaging types */ diff --git a/src/ocre/ocre_messaging/ocre_messaging.c b/src/ocre/ocre_messaging/ocre_messaging.c index 3709e8f5..13bdc7b8 100644 --- a/src/ocre/ocre_messaging/ocre_messaging.c +++ b/src/ocre/ocre_messaging/ocre_messaging.c @@ -14,7 +14,7 @@ LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); #ifndef CONFIG_MESSAGING_MAX_SUBSCRIPTIONS -#define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 32 +#define CONFIG_MESSAGING_MAX_SUBSCRIPTIONS 10 #endif #define OCRE_MAX_TOPIC_LEN 64 diff --git a/src/ocre/ocre_messaging/ocre_messaging.h b/src/ocre/ocre_messaging/ocre_messaging.h index eaa2ebdf..d46eb56e 100644 --- a/src/ocre/ocre_messaging/ocre_messaging.h +++ b/src/ocre/ocre_messaging/ocre_messaging.h @@ -26,49 +26,53 @@ typedef struct { } ocre_msg_t; /** - * @brief Initialize the messaging system. - * - * @return 0 on success, negative error code on failure. + * @brief Initialize the OCRE messaging system. */ int ocre_messaging_init(void); /** - * @brief Subscribe to a topic. + * @brief Publish a message to the specified topic. * * @param exec_env WASM execution environment. - * @param topic Topic to subscribe to. + * @param topic The name of the topic to publish to (pointer). + * @param content_type The content type of the message (e.g., MIME type, pointer). + * @param payload The message payload. + * @param payload_len The length of the payload. * @return 0 on success, negative error code on failure. */ -int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic); +int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len); /** - * @brief Publish a message to a topic. + * @brief Subscribe to messages on a specified topic. * * @param exec_env WASM execution environment. - * @param topic Topic to publish to. - * @param content_type Content type of the message. - * @param payload Message payload. - * @param payload_len Length of the payload. + * @param topic The name of the topic to subscribe to (pointer). * @return 0 on success, negative error code on failure. */ -int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_type, void *payload, int payload_len); +int ocre_messaging_subscribe(wasm_exec_env_t exec_env, void *topic); /** - * @brief Free module event data. + * @brief Clean up messaging resources for a WASM module. * - * @param exec_env WASM execution environment. - * @param topic_offset Topic offset in WASM memory. - * @param content_offset Content type offset in WASM memory. - * @param payload_offset Payload offset in WASM memory. - * @return 0 on success, negative error code on failure. + * @param module_inst The WASM module instance to clean up. */ -int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, uint32_t payload_offset); +void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst); /** - * @brief Cleanup messaging resources for a module. + * @brief Frees allocated memory for a messaging event in the WASM module. * - * @param module_inst WASM module instance. + * This function releases the allocated memory for the topic, content-type, and payload + * associated with a messaging event received by the WASM module. It should be called + * after processing the message to prevent memory leaks. + * + * @param exec_env WASM execution environment. + * @param topic_offset Offset in WASM memory for the message topic. + * @param content_offset Offset in WASM memory for the message content-type. + * @param payload_offset Offset in WASM memory for the message payload. + * + * @return OCRE_SUCCESS on success, negative error code on failure. */ -void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst); +int ocre_messaging_free_module_event_data(wasm_exec_env_t exec_env, uint32_t topic_offset, uint32_t content_offset, + uint32_t payload_offset); #endif /* OCRE_MESSAGING_H */ From abb1bcc1ca7fc8875cbc1e4146b9786cc7140790 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:53:24 +0200 Subject: [PATCH 18/26] Unify zephyr timers Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/ocre_timers/ocre_timer.c | 211 ++++++++---------------------- 1 file changed, 54 insertions(+), 157 deletions(-) diff --git a/src/ocre/ocre_timers/ocre_timer.c b/src/ocre/ocre_timers/ocre_timer.c index 0d49ae41..ec561233 100644 --- a/src/ocre/ocre_timers/ocre_timer.c +++ b/src/ocre/ocre_timers/ocre_timer.c @@ -20,34 +20,18 @@ LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); /* Timer type definition */ typedef uint32_t ocre_timer_t; -/* Platform-specific timer structures */ -#ifdef __ZEPHYR__ -// Compact timer structure for Zephyr +/* Unified timer structure using core_timer API */ typedef struct { uint32_t in_use: 1; uint32_t id: 8; // Up to 256 timers uint32_t interval: 16; // Up to 65s intervals uint32_t periodic: 1; - struct k_timer timer; + uint32_t running: 1; // Track if timer is currently running + uint32_t start_time; // Start time for remaining time calculations + core_timer_t timer; // Unified core timer wasm_module_inst_t owner; } ocre_timer_internal; -#else /* POSIX */ -// POSIX timer structure -typedef struct { - uint32_t in_use: 1; - uint32_t id: 8; // Up to 256 timers - uint32_t interval: 16; // Up to 65s intervals - uint32_t periodic: 1; - timer_t timer; - pthread_t thread; - bool thread_running; - wasm_module_inst_t owner; -} ocre_timer_internal; - -/* POSIX timer thread function - not used currently */ -#endif - #ifndef CONFIG_MAX_TIMER #define CONFIG_MAX_TIMERS 5 #endif @@ -56,12 +40,7 @@ typedef struct { static ocre_timer_internal timers[CONFIG_MAX_TIMERS]; static bool timer_system_initialized = false; -#ifdef __ZEPHYR__ -static void timer_callback_wrapper(struct k_timer *timer); -#else -static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc); -static void posix_send_timer_event(int timer_id); -#endif +static void unified_timer_callback(void *user_data); void ocre_timer_init(void) { if (timer_system_initialized) { @@ -74,18 +53,6 @@ void ocre_timer_init(void) { return; } -#ifndef __ZEPHYR__ - // Setup POSIX signal handler for timer callbacks - struct sigaction sa; - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = posix_timer_signal_handler; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGALRM, &sa, NULL) == -1) { - LOG_ERR("Failed to setup POSIX timer signal handler"); - return; - } -#endif - ocre_register_cleanup_handler(OCRE_RESOURCE_TYPE_TIMER, ocre_timer_cleanup_container); timer_system_initialized = true; LOG_INF("Timer system initialized"); @@ -108,22 +75,12 @@ int ocre_timer_create(wasm_exec_env_t exec_env, int id) { timer->owner = module; timer->in_use = 1; -#ifdef __ZEPHYR__ - k_timer_init(&timer->timer, timer_callback_wrapper, NULL); -#else - struct sigevent sev; - memset(&sev, 0, sizeof(sev)); - sev.sigev_notify = SIGEV_SIGNAL; - sev.sigev_signo = SIGALRM; - sev.sigev_value.sival_int = id; - - if (timer_create(CLOCK_REALTIME, &sev, &timer->timer) == -1) { - LOG_ERR("Failed to create POSIX timer %d", id); + // Initialize unified core timer + if (core_timer_init(&timer->timer, unified_timer_callback, timer) != 0) { + LOG_ERR("Failed to initialize core timer %d", id); timer->in_use = 0; return -EINVAL; } - timer->thread_running = false; -#endif ocre_increment_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); LOG_INF("Created timer %d for module %p", id, (void *)module); @@ -143,17 +100,11 @@ int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id) { return -EINVAL; } -#ifdef __ZEPHYR__ - k_timer_stop(&timer->timer); -#else - timer_delete(timer->timer); - if (timer->thread_running) { - pthread_cancel(timer->thread); - timer->thread_running = false; - } -#endif + // Stop unified core timer + core_timer_stop(&timer->timer); timer->in_use = 0; + timer->running = 0; timer->owner = NULL; ocre_decrement_resource_count(module, OCRE_RESOURCE_TYPE_TIMER); LOG_INF("Deleted timer %d", id); @@ -180,29 +131,16 @@ int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, in timer->interval = interval; timer->periodic = is_periodic; + timer->start_time = core_uptime_get(); + timer->running = 1; -#ifdef __ZEPHYR__ - k_timeout_t duration = K_MSEC(interval); - k_timeout_t period = is_periodic ? duration : K_NO_WAIT; - k_timer_start(&timer->timer, duration, period); -#else - struct itimerspec its; - its.it_value.tv_sec = interval / 1000; - its.it_value.tv_nsec = (interval % 1000) * 1000000; - - if (is_periodic) { - its.it_interval.tv_sec = its.it_value.tv_sec; - its.it_interval.tv_nsec = its.it_value.tv_nsec; - } else { - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - } - - if (timer_settime(timer->timer, 0, &its, NULL) == -1) { - LOG_ERR("Failed to start POSIX timer %d", id); + // Start unified core timer + int period_ms = is_periodic ? interval : 0; + if (core_timer_start(&timer->timer, interval, period_ms) != 0) { + LOG_ERR("Failed to start core timer %d", id); + timer->running = 0; return -EINVAL; } -#endif LOG_INF("Started timer %d with interval %dms, periodic=%d", id, interval, is_periodic); return 0; @@ -221,13 +159,9 @@ int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id) { return -EINVAL; } -#ifdef __ZEPHYR__ - k_timer_stop(&timer->timer); -#else - struct itimerspec its; - memset(&its, 0, sizeof(its)); - timer_settime(timer->timer, 0, &its, NULL); -#endif + // Stop unified core timer + core_timer_stop(&timer->timer); + timer->running = 0; LOG_INF("Stopped timer %d", id); return 0; @@ -247,16 +181,17 @@ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id) { } int remaining; -#ifdef __ZEPHYR__ - remaining = k_ticks_to_ms_floor32(k_timer_remaining_ticks(&timer->timer)); -#else - struct itimerspec its; - if (timer_gettime(timer->timer, &its) == -1) { - LOG_ERR("Failed to get remaining time for timer %d", id); - return -EINVAL; + if (!timer->running) { + remaining = 0; + } else { + uint32_t current_time = core_uptime_get(); + uint32_t elapsed = current_time - timer->start_time; + if (elapsed >= timer->interval) { + remaining = 0; // Timer should have expired + } else { + remaining = timer->interval - elapsed; + } } - remaining = its.it_value.tv_sec * 1000 + its.it_value.tv_nsec / 1000000; -#endif LOG_INF("Timer %d remaining time: %dms", id, remaining); return remaining; @@ -270,16 +205,10 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { if (timers[i].in_use && timers[i].owner == module_inst) { -#ifdef __ZEPHYR__ - k_timer_stop(&timers[i].timer); -#else - timer_delete(timers[i].timer); - if (timers[i].thread_running) { - pthread_cancel(timers[i].thread); - timers[i].thread_running = false; - } -#endif + // Stop unified core timer + core_timer_stop(&timers[i].timer); timers[i].in_use = 0; + timers[i].running = 0; timers[i].owner = NULL; ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_TIMER); LOG_INF("Cleaned up timer %d for module %p", i + 1, (void *)module_inst); @@ -288,74 +217,42 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { LOG_INF("Cleaned up timer resources for module %p", (void *)module_inst); } -#ifdef __ZEPHYR__ -static void timer_callback_wrapper(struct k_timer *timer) { +/* Unified timer callback using core_timer API */ +static void unified_timer_callback(void *user_data) { if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); return; } - if (!timer) { - LOG_ERR("Null timer pointer in callback"); - return; - } - LOG_DBG("Timer callback for timer %p", (void *)timer); - LOG_DBG("ocre_event_queue at %p", (void *)&ocre_event_queue); - for (int i = 0; i < CONFIG_MAX_TIMERS; i++) { - if (timers[i].in_use && &timers[i].timer == timer && timers[i].owner) { - ocre_event_t event; - event.type = OCRE_RESOURCE_TYPE_TIMER; - event.data.timer_event.timer_id = timers[i].id; - event.owner = timers[i].owner; - - LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, event.data.timer_event.timer_id, - (void *)timers[i].owner); - core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); - if (core_eventq_put(&ocre_event_queue, &event) != 0) { - LOG_ERR("Failed to queue timer event for timer %d", timers[i].id); - } else { - LOG_DBG("Queued timer event for timer %d", timers[i].id); - } - core_spinlock_unlock(&ocre_event_queue_lock, key); - } - } -} - -#else /* POSIX */ - -static void posix_timer_signal_handler(int sig, siginfo_t *si, void *uc) { - (void)sig; - (void)uc; - if (si && si->si_value.sival_int > 0 && si->si_value.sival_int <= CONFIG_MAX_TIMERS) { - posix_send_timer_event(si->si_value.sival_int); - } -} - -static void posix_send_timer_event(int timer_id) { - if (!timer_system_initialized || !common_initialized || !ocre_event_queue_initialized) { - LOG_ERR("Timer, common, or event queue not initialized, skipping callback"); + + ocre_timer_internal *timer = (ocre_timer_internal *)user_data; + if (!timer || !timer->in_use || !timer->owner) { + LOG_ERR("Invalid timer in callback: %p", (void *)timer); return; } - int index = timer_id - 1; - if (index < 0 || index >= CONFIG_MAX_TIMERS || !timers[index].in_use) { - LOG_ERR("Invalid timer ID %d in callback", timer_id); - return; + LOG_DBG("Timer callback for timer %d", timer->id); + + // For non-periodic timers, mark as not running + if (!timer->periodic) { + timer->running = 0; + } else { + // For periodic timers, update start time for next cycle + timer->start_time = core_uptime_get(); } + // Create and queue timer event ocre_event_t event; event.type = OCRE_RESOURCE_TYPE_TIMER; - event.data.timer_event.timer_id = timer_id; - event.owner = timers[index].owner; + event.data.timer_event.timer_id = timer->id; + event.owner = timer->owner; - LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer_id, (void *)timers[index].owner); + LOG_DBG("Creating timer event: type=%d, id=%d, for owner %p", event.type, timer->id, (void *)timer->owner); core_spinlock_key_t key = core_spinlock_lock(&ocre_event_queue_lock); if (core_eventq_put(&ocre_event_queue, &event) != 0) { - LOG_ERR("Failed to queue timer event for timer %d", timer_id); + LOG_ERR("Failed to queue timer event for timer %d", timer->id); } else { - LOG_DBG("Queued timer event for timer %d", timer_id); + LOG_DBG("Queued timer event for timer %d", timer->id); } core_spinlock_unlock(&ocre_event_queue_lock, key); } - -#endif From cff26dd58cb8016698692205298d65c193b81702 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:59:07 +0200 Subject: [PATCH 19/26] Make less changes to timers Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/ocre_timers/ocre_timer.c | 3 -- src/ocre/ocre_timers/ocre_timer.h | 77 ++++++++++++++++--------------- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/ocre/ocre_timers/ocre_timer.c b/src/ocre/ocre_timers/ocre_timer.c index ec561233..c2b57293 100644 --- a/src/ocre/ocre_timers/ocre_timer.c +++ b/src/ocre/ocre_timers/ocre_timer.c @@ -17,9 +17,6 @@ LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); -/* Timer type definition */ -typedef uint32_t ocre_timer_t; - /* Unified timer structure using core_timer API */ typedef struct { uint32_t in_use: 1; diff --git a/src/ocre/ocre_timers/ocre_timer.h b/src/ocre/ocre_timers/ocre_timer.h index a47194ed..1cdf1289 100644 --- a/src/ocre/ocre_timers/ocre_timer.h +++ b/src/ocre/ocre_timers/ocre_timer.h @@ -11,68 +11,73 @@ #include #include "ocre_core_external.h" -#ifndef OCRE_TIMER_T_DEFINED -#define OCRE_TIMER_T_DEFINED -typedef uint32_t ocre_timer_t; -#endif +typedef int ocre_timer_t; /** - * @brief Initialize the timer system. + * @brief Timer callback function type + * @param timer_id ID of the expired timer */ -void ocre_timer_init(void); +typedef void (*timer_dispatcher_t)(uint32_t timer_id); /** - * @brief Create a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return 0 on success, negative error code on failure. + * @brief Creates a new timer instance + * @param exec_env WASM execution environment + * @param id Unique timer identifier (1-CONFIG_MAX_TIMERS) + * @return 0 on success, -1 on error with errno set + * @retval EINVAL Invalid ID or timer system not initialized + * @retval EEXIST Timer ID already in use */ int ocre_timer_create(wasm_exec_env_t exec_env, int id); /** - * @brief Delete a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return 0 on success, negative error code on failure. + * @brief Deletes a timer instance + * @param exec_env WASM execution environment + * @param id Timer identifier to delete + * @return 0 on success, -1 on error with errno set + * @retval EINVAL Timer not found or not in use */ int ocre_timer_delete(wasm_exec_env_t exec_env, ocre_timer_t id); /** - * @brief Start a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @param interval Timer interval in milliseconds. - * @param is_periodic Whether the timer is periodic. - * @return 0 on success, negative error code on failure. + * @brief Starts a timer with specified parameters + * @param exec_env WASM execution environment + * @param id Timer identifier to start + * @param interval Initial expiration time in milliseconds + * @param is_periodic 1 for periodic timer, 0 for one-shot + * @return 0 on success, -1 on error with errno set + * @retval EINVAL Invalid timer ID or interval <= 0 */ int ocre_timer_start(wasm_exec_env_t exec_env, ocre_timer_t id, int interval, int is_periodic); /** - * @brief Stop a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return 0 on success, negative error code on failure. + * @brief Stops a running timer + * @param exec_env WASM execution environment + * @param id Timer identifier to stop + * @return 0 on success, -1 on error with errno set + * @retval EINVAL Timer not found or not in use */ int ocre_timer_stop(wasm_exec_env_t exec_env, ocre_timer_t id); /** - * @brief Get remaining time for a timer. - * - * @param exec_env WASM execution environment. - * @param id Timer ID. - * @return Remaining time in milliseconds, or negative error code on failure. + * @brief Gets the remaining time for a timer + * @param exec_env WASM execution environment + * @param id Timer identifier + * @return Remaining time in milliseconds, or -1 on error with errno set + * @retval EINVAL Invalid timer ID or timer not found */ int ocre_timer_get_remaining(wasm_exec_env_t exec_env, ocre_timer_t id); /** - * @brief Cleanup timer resources for a module. - * - * @param module_inst WASM module instance. + * @brief Cleans up all timers associated with a WASM module instance + * @param module_inst WASM module instance to clean up */ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst); +/** + * @brief Initializes the timer subsystem + * @note Must be called once before any other timer operations + */ +void ocre_timer_init(void); + +int ocre_timer_set_callback(wasm_exec_env_t exec_env, const char *callback_name); #endif /* OCRE_TIMER_H */ From cda5d96458fbb9cb3386c5cdc99d3b06c953654a Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:24:20 +0200 Subject: [PATCH 20/26] Fix log levels Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 37be0d37..809c4199 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -14,7 +14,7 @@ #include #include -LOG_MODULE_REGISTER(ocre_common, LOG_LEVEL_DBG); +LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); #ifdef CONFIG_OCRE_GPIO #include "../ocre_gpio/ocre_gpio.h" From e31d7c9e7b095795b6f54c075bea9a9050374241 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Mon, 27 Oct 2025 08:59:22 +0100 Subject: [PATCH 21/26] Add blinky test to Linux Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8358e447..3263c5ea 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -153,6 +153,9 @@ jobs: - name: filesystem-full expected: "Directory listing for" path: generic/filesystem-full + - name: blinky + expected: "blink (count: 1, state: -)" + path: generic/blinky # Add here more samples steps: - name: Checkout current repository From 644a155a28a6997d381eaf0088acb72b96c90754 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Mon, 27 Oct 2025 09:31:14 +0100 Subject: [PATCH 22/26] Cleanup minor messages and defines Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/api/ocre_common.c | 20 ++++---------------- src/ocre/api/ocre_common.h | 10 ---------- src/ocre/ocre_messaging/ocre_messaging.c | 5 +++++ 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/ocre/api/ocre_common.c b/src/ocre/api/ocre_common.c index 809c4199..f8362fdd 100644 --- a/src/ocre/api/ocre_common.c +++ b/src/ocre/api/ocre_common.c @@ -21,7 +21,6 @@ LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); #endif #ifdef CONFIG_OCRE_CONTAINER_MESSAGING -#include "../ocre_timers/ocre_timer.h" #include "../ocre_messaging/ocre_messaging.h" #endif @@ -192,13 +191,14 @@ int ocre_common_init(void) { while (core_eventq_get(&ocre_event_queue, &dummy) == 0) { LOG_INF("Purged stale event from queue"); } - + + /* Temporary platform-specific initialization */ #ifdef __ZEPHYR__ /* No additional Zephyr-specific initialization needed */ #else /* POSIX */ pthread_mutex_init(&ocre_event_queue_lock.mutex, NULL); #endif - + ocre_event_queue_initialized = true; #if EVENT_THREAD_POOL_SIZE > 0 LOG_INF("ocre_event_queue initialized at %p, size=%d", (void *)&ocre_event_queue, sizeof(ocre_event_t)); @@ -306,24 +306,16 @@ ocre_module_context_t *ocre_get_module_context(wasm_module_inst_t module_inst) { LOG_ERR("Null module instance"); return NULL; } - - LOG_DBG("Looking for module context: %p", (void *)module_inst); - - int count = 0; - core_mutex_lock(®istry_mutex); for (core_snode_t *current = module_registry.head; current != NULL; current = current->next) { module_node_t *node = (module_node_t *)((char *)current - offsetof(module_node_t, node)); - LOG_DBG(" Registry entry %d: %p", count++, (void *)node->ctx.inst); if (node->ctx.inst == module_inst) { node->ctx.last_activity = core_uptime_get(); core_mutex_unlock(®istry_mutex); - LOG_DBG("Found module context for %p", (void *)module_inst); return &node->ctx; } } core_mutex_unlock(®istry_mutex); - LOG_ERR("Module context not found for %p", (void *)module_inst); return NULL; } @@ -334,12 +326,8 @@ int ocre_register_dispatcher(wasm_exec_env_t exec_env, ocre_resource_type_t type function_name ? function_name : "null"); return -EINVAL; } - - LOG_DBG("ocre_register_dispatcher: exec_env=%p, type=%d, func=%s", (void *)exec_env, type, function_name); - LOG_DBG("current_module_tls = %p", current_module_tls ? (void *)*current_module_tls : NULL); - + wasm_module_inst_t module_inst = current_module_tls ? *current_module_tls : wasm_runtime_get_module_inst(exec_env); - LOG_DBG("Retrieved module_inst = %p", (void *)module_inst); if (!module_inst) { LOG_ERR("No module instance for event type %d", type); diff --git a/src/ocre/api/ocre_common.h b/src/ocre/api/ocre_common.h index 0789093e..95be03a9 100644 --- a/src/ocre/api/ocre_common.h +++ b/src/ocre/api/ocre_common.h @@ -14,16 +14,6 @@ #include "ocre_core_external.h" #include "../ocre_messaging/ocre_messaging.h" -/* Platform-specific includes */ -#ifdef __ZEPHYR__ -#include -#include -#else -#include -/* Forward declarations for POSIX messaging types */ -struct ocre_messaging_event; -#endif - #define OCRE_EVENT_THREAD_STACK_SIZE 2048 #define OCRE_EVENT_THREAD_PRIORITY 5 #define OCRE_WASM_STACK_SIZE 16384 diff --git a/src/ocre/ocre_messaging/ocre_messaging.c b/src/ocre/ocre_messaging/ocre_messaging.c index 13bdc7b8..a27b48f7 100644 --- a/src/ocre/ocre_messaging/ocre_messaging.c +++ b/src/ocre/ocre_messaging/ocre_messaging.c @@ -40,6 +40,11 @@ int ocre_messaging_init(void) { LOG_INF("Messaging system already initialized"); return 0; } + + if (!common_initialized && ocre_common_init() != 0) { + LOG_ERR("Failed to initialize common subsystem"); + return -EAGAIN; + } memset(&messaging_system, 0, sizeof(ocre_messaging_system_t)); From 1536bd45fb9cac60960572a9cc608d456969734e Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Mon, 27 Oct 2025 09:39:03 +0100 Subject: [PATCH 23/26] Add log leveling Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/shared/platform/posix/core_internal.h | 57 +++++++++++++++++++---- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/src/shared/platform/posix/core_internal.h b/src/shared/platform/posix/core_internal.h index 15a62bc3..c3f8f47b 100644 --- a/src/shared/platform/posix/core_internal.h +++ b/src/shared/platform/posix/core_internal.h @@ -45,25 +45,66 @@ #define LOG_MODULE_DECLARE(name, level) +/* + * @brief Log level priority definitions (highest to lowest) + */ +#define APP_LOG_LEVEL_ERR 1 +#define APP_LOG_LEVEL_WRN 2 +#define APP_LOG_LEVEL_INF 3 +#define APP_LOG_LEVEL_DBG 4 + +/* + * @brief Determine the current log level based on CONFIG defines + * Priority: CONFIG_LOG_LVL_ERR > CONFIG_LOG_LVL_WRN > CONFIG_LOG_LVL_INF > CONFIG_LOG_LVL_DBG + * If none specified, default to INFO level + */ +#if defined(CONFIG_LOG_LVL_ERR) + #define APP_CURRENT_LOG_LEVEL APP_LOG_LEVEL_ERR +#elif defined(CONFIG_LOG_LVL_WRN) + #define APP_CURRENT_LOG_LEVEL APP_LOG_LEVEL_WRN +#elif defined(CONFIG_LOG_LVL_INF) + #define APP_CURRENT_LOG_LEVEL APP_LOG_LEVEL_INF +#elif defined(CONFIG_LOG_LVL_DBG) + #define APP_CURRENT_LOG_LEVEL APP_LOG_LEVEL_DBG +#else + #define APP_CURRENT_LOG_LEVEL APP_LOG_LEVEL_INF /* Default to INFO level */ +#endif + /** - * @brief Log a debug message. + * @brief Log an error message (always shown if ERR level or higher). */ -#define LOG_DBG(fmt, ...) printf("[DEBUG] " fmt "\n", ##__VA_ARGS__) +#if APP_CURRENT_LOG_LEVEL >= APP_LOG_LEVEL_ERR + #define LOG_ERR(fmt, ...) printf("[ERROR] " fmt "\n", ##__VA_ARGS__) +#else + #define LOG_ERR(fmt, ...) do { } while(0) +#endif /** - * @brief Log an error message. + * @brief Log a warning message (shown if WRN level or higher). */ -#define LOG_ERR(fmt, ...) printf("[ERROR] " fmt "\n", ##__VA_ARGS__) +#if APP_CURRENT_LOG_LEVEL >= APP_LOG_LEVEL_WRN + #define LOG_WRN(fmt, ...) printf("[WARNING] " fmt "\n", ##__VA_ARGS__) +#else + #define LOG_WRN(fmt, ...) do { } while(0) +#endif /** - * @brief Log a warning message. + * @brief Log an informational message (shown if INF level or higher). */ -#define LOG_WRN(fmt, ...) printf("[WARNING] " fmt "\n", ##__VA_ARGS__) +#if APP_CURRENT_LOG_LEVEL >= APP_LOG_LEVEL_INF + #define LOG_INF(fmt, ...) printf("[INFO] " fmt "\n", ##__VA_ARGS__) +#else + #define LOG_INF(fmt, ...) do { } while(0) +#endif /** - * @brief Log an informational message. + * @brief Log a debug message (shown only if DBG level). */ -#define LOG_INF(fmt, ...) printf("[INFO] " fmt "\n", ##__VA_ARGS__) +#if APP_CURRENT_LOG_LEVEL >= APP_LOG_LEVEL_DBG + #define LOG_DBG(fmt, ...) printf("[DEBUG] " fmt "\n", ##__VA_ARGS__) +#else + #define LOG_DBG(fmt, ...) do { } while(0) +#endif // Constants From 7988ec076f4d2c9a085b5d00d02761a8465f3a3d Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Mon, 27 Oct 2025 09:42:59 +0100 Subject: [PATCH 24/26] Update Readme Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3c7e270c..5c256690 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,19 @@ Our mission is to make it as easy to develop and securely deploy apps for the bi Ocre supports a range of features depending on the platform. The table below summarizes the current support: -| Feature | Zephyr (native_sim, b_u585i_iot02a) | Linux x86_64 | +| Feature | Zephyr (native_sim, b_u585i_iot02a) | Linux | |------------------------|:-----------------------------------:|:-------------:| | Ocre Runtime | ✅ | ✅ | -| Container Messaging | ✅ | ❌ | +| Container Messaging | ✅ | ✅ | | GPIO | ✅ | ❌ | -| Timers | ✅ | ❌ | +| Timers | ✅ | ✅ | | Sensors | ✅ | ❌ | -| Networking | ❌ | ✅ | +| Networking | ✅ | ✅ | +| Filesystem | ✅ | ✅ | | Interactive Shell | ✅ | ❌ | - **Zephyr**: Full feature set, including hardware integration and shell. -- **Linux x86_64**: Core runtime and networking only; hardware and shell features are not available. +- **Linux**: Core runtime and multiple I/O features; hardware and shell features are not available. --- From 6ea3432b681fb98bd0353b9d0a7f89d52008676d Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Mon, 27 Oct 2025 10:36:22 +0100 Subject: [PATCH 25/26] Fix errors on linux side Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/components/container_supervisor/cs_sm_impl.c | 7 +++---- src/ocre/ocre_gpio/ocre_gpio.c | 4 ++-- src/ocre/ocre_messaging/ocre_messaging.c | 6 +++--- src/ocre/ocre_timers/ocre_timer.c | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ocre/components/container_supervisor/cs_sm_impl.c b/src/ocre/components/container_supervisor/cs_sm_impl.c index 8b96f4a6..c86a4fdc 100644 --- a/src/ocre/components/container_supervisor/cs_sm_impl.c +++ b/src/ocre/components/container_supervisor/cs_sm_impl.c @@ -128,10 +128,9 @@ static void container_thread_entry(void *args) { #endif // Run the WASM main function bool success = wasm_application_execute_main(module_inst, 0, NULL); - // Update container status - container->container_runtime_status = success ? CONTAINER_STATUS_STOPPED : CONTAINER_STATUS_ERROR; - + if (container->container_runtime_status != CONTAINER_STATUS_STOPPED) + container->container_runtime_status = success ? CONTAINER_STATUS_STOPPED : CONTAINER_STATUS_ERROR; // Cleanup sequence core_mutex_lock(&container->lock); { @@ -302,7 +301,7 @@ ocre_container_status_t CS_create_container(ocre_container_t *container) { if (container->container_runtime_status != CONTAINER_STATUS_UNKNOWN && container->container_runtime_status != CONTAINER_STATUS_DESTROYED) { LOG_ERR("Cannot create container again container with ID: %d, already exists", curr_container_ID); - return RUNTIME_STATUS_ERROR; + return CONTAINER_STATUS_ERROR; } if (!validate_container_memory(container)) { diff --git a/src/ocre/ocre_gpio/ocre_gpio.c b/src/ocre/ocre_gpio/ocre_gpio.c index 68e4ade7..63004048 100644 --- a/src/ocre/ocre_gpio/ocre_gpio.c +++ b/src/ocre/ocre_gpio/ocre_gpio.c @@ -266,10 +266,10 @@ void ocre_gpio_cleanup_container(wasm_module_inst_t module_inst) { gpio_pins[i].in_use = 0; gpio_pins[i].owner = NULL; ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_GPIO); - LOG_INF("Cleaned up GPIO pin %d", i); + LOG_DBG("Cleaned up GPIO pin %d", i); } } - LOG_INF("Cleaned up GPIO resources for module %p", (void *)module_inst); + LOG_DBG("Cleaned up GPIO resources for module %p", (void *)module_inst); } void ocre_gpio_set_dispatcher(wasm_exec_env_t exec_env) { diff --git a/src/ocre/ocre_messaging/ocre_messaging.c b/src/ocre/ocre_messaging/ocre_messaging.c index a27b48f7..29cfe5c2 100644 --- a/src/ocre/ocre_messaging/ocre_messaging.c +++ b/src/ocre/ocre_messaging/ocre_messaging.c @@ -72,13 +72,13 @@ void ocre_messaging_cleanup_container(wasm_module_inst_t module_inst) { messaging_system.subscriptions[i].topic[0] = '\0'; messaging_system.subscription_count--; ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_MESSAGING); - LOG_INF("Cleaned up subscription %d for module %p", i, (void *)module_inst); + LOG_DBG("Cleaned up subscription %d for module %p", i, (void *)module_inst); } } core_mutex_unlock(&messaging_system.mutex); - LOG_INF("Cleaned up messaging resources for module %p", (void *)module_inst); + LOG_DBG("Cleaned up messaging resources for module %p", (void *)module_inst); } /* Subscribe to a topic */ @@ -253,7 +253,7 @@ int ocre_messaging_publish(wasm_exec_env_t exec_env, void *topic, void *content_ message_id++; return 0; } else { - LOG_ERR("No matching subscriptions found for topic %s", (char *)topic); + LOG_WRN("No matching subscriptions found for topic %s", (char *)topic); return -ENOENT; } } diff --git a/src/ocre/ocre_timers/ocre_timer.c b/src/ocre/ocre_timers/ocre_timer.c index c2b57293..16b9491b 100644 --- a/src/ocre/ocre_timers/ocre_timer.c +++ b/src/ocre/ocre_timers/ocre_timer.c @@ -208,10 +208,10 @@ void ocre_timer_cleanup_container(wasm_module_inst_t module_inst) { timers[i].running = 0; timers[i].owner = NULL; ocre_decrement_resource_count(module_inst, OCRE_RESOURCE_TYPE_TIMER); - LOG_INF("Cleaned up timer %d for module %p", i + 1, (void *)module_inst); + LOG_DBG("Cleaned up timer %d for module %p", i + 1, (void *)module_inst); } } - LOG_INF("Cleaned up timer resources for module %p", (void *)module_inst); + LOG_DBG("Cleaned up timer resources for module %p", (void *)module_inst); } /* Unified timer callback using core_timer API */ From 3137afb9931c1a5105ef0fe3029b69b875f61946 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Tue, 28 Oct 2025 07:11:32 +0100 Subject: [PATCH 26/26] Fix macro definition Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- src/ocre/ocre_timers/ocre_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ocre/ocre_timers/ocre_timer.c b/src/ocre/ocre_timers/ocre_timer.c index 16b9491b..02a67d91 100644 --- a/src/ocre/ocre_timers/ocre_timer.c +++ b/src/ocre/ocre_timers/ocre_timer.c @@ -29,7 +29,7 @@ typedef struct { wasm_module_inst_t owner; } ocre_timer_internal; -#ifndef CONFIG_MAX_TIMER +#ifndef CONFIG_MAX_TIMERS #define CONFIG_MAX_TIMERS 5 #endif