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 <anas.nashif@intel.com>
This commit is contained in:
Anas Nashif 2019-05-04 10:36:14 -04:00
commit 928af3ce09
2 changed files with 17 additions and 8 deletions

View file

@ -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);
/**

View file

@ -28,6 +28,7 @@
#include <init.h>
#include <syscall_handler.h>
#include <debug/tracing.h>
#include <sys/check.h>
/* 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 <syscalls/k_sem_init_mrsh.c>
#endif