From 928af3ce09cbbd91c5b5e5c14200046956ba7b9b Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 4 May 2019 10:36:14 -0400 Subject: [PATCH] kernel: semaphore: k_sem_init error checking Check for errors at runtime and stop depending on ASSERTs. This changes the API for - k_sem_init k_sem_init now returns -EINVAL on invalid data. Signed-off-by: Anas Nashif --- include/kernel.h | 6 ++++-- kernel/sem.c | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/kernel.h b/include/kernel.h index 1587b784ca3..4224c1ea2b1 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -3443,10 +3443,12 @@ struct k_sem { * @param initial_count Initial semaphore count. * @param limit Maximum permitted semaphore count. * - * @return N/A + * @retval 0 Semaphore created successfully + * @retval -EINVAL Invalid values + * * @req K-SEM-001 */ -__syscall void k_sem_init(struct k_sem *sem, unsigned int initial_count, +__syscall int k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit); /** diff --git a/kernel/sem.c b/kernel/sem.c index ef895d3c437..bc31e052d2d 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -28,6 +28,7 @@ #include #include #include +#include /* We use a system-wide lock to synchronize semaphores, which has * unfortunate performance impact vs. using a per-object lock @@ -59,11 +60,16 @@ SYS_INIT(init_sem_module, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); #endif /* CONFIG_OBJECT_TRACING */ -void z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, +int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) { - __ASSERT(limit != 0U, "limit cannot be zero"); - __ASSERT(initial_count <= limit, "count cannot be greater than limit"); + /* + * Limit cannot be zero and count cannot be greater than limit + */ + CHECKIF(limit == 0U || initial_count > limit) { + return -EINVAL; + } + sys_trace_void(SYS_TRACE_ID_SEMA_INIT); sem->count = initial_count; @@ -77,15 +83,16 @@ void z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, z_object_init(sem); sys_trace_end_call(SYS_TRACE_ID_SEMA_INIT); + + return 0; } #ifdef CONFIG_USERSPACE -void z_vrfy_k_sem_init(struct k_sem *sem, unsigned int initial_count, +int z_vrfy_k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) { Z_OOPS(Z_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM)); - Z_OOPS(Z_SYSCALL_VERIFY(limit != 0 && initial_count <= limit)); - z_impl_k_sem_init(sem, initial_count, limit); + return z_impl_k_sem_init(sem, initial_count, limit); } #include #endif