kernel: Provide only one _SYSCALL_HANDLER() macro

Use some preprocessor trickery to automatically deduce the amount of
arguments for the various _SYSCALL_HANDLERn() macros.  Makes the grunt
work of converting a bunch of kernel APIs to system calls slightly
easier.

Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
Leandro Pereira 2017-10-13 14:00:22 -07:00 committed by Anas Nashif
commit 6f99bdb02a
15 changed files with 56 additions and 42 deletions

View file

@ -101,7 +101,7 @@ int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER2(k_alert_recv, alert, timeout)
_SYSCALL_HANDLER(k_alert_recv, alert, timeout)
{
_SYSCALL_OBJ(alert, K_OBJ_ALERT);
return _impl_k_alert_recv((struct k_alert *)alert, timeout);

View file

@ -277,11 +277,12 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
* the bolierplate. The macros ensure that the seventh argument is named
* "ssf" as this is now referenced by various other _SYSCALL macros.
*
* The different variants here simply depend on how many of the 6 arguments
* passed in are really used.
* Use the _SYSCALL_HANDLER(name_, arg0, ..., arg6) variant, as it will
* automatically deduce the correct version of __SYSCALL_HANDLERn() to
* use depending on the number of arguments.
*/
#define _SYSCALL_HANDLER0(name_) \
#define __SYSCALL_HANDLER0(name_) \
u32_t _handler_ ## name_(u32_t arg1 __unused, \
u32_t arg2 __unused, \
u32_t arg3 __unused, \
@ -290,7 +291,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER1(name_, arg1_) \
#define __SYSCALL_HANDLER1(name_, arg1_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2 __unused, \
u32_t arg3 __unused, \
@ -299,7 +300,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER2(name_, arg1_, arg2_) \
#define __SYSCALL_HANDLER2(name_, arg1_, arg2_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3 __unused, \
@ -308,7 +309,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER3(name_, arg1_, arg2_, arg3_) \
#define __SYSCALL_HANDLER3(name_, arg1_, arg2_, arg3_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
@ -317,7 +318,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER4(name_, arg1_, arg2_, arg3_, arg4_) \
#define __SYSCALL_HANDLER4(name_, arg1_, arg2_, arg3_, arg4_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
@ -326,7 +327,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER5(name_, arg1_, arg2_, arg3_, arg4_, arg5_) \
#define __SYSCALL_HANDLER5(name_, arg1_, arg2_, arg3_, arg4_, arg5_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
@ -335,7 +336,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER6(name_, arg1_, arg2_, arg3_, arg4_, arg5_, arg6_) \
#define __SYSCALL_HANDLER6(name_, arg1_, arg2_, arg3_, arg4_, arg5_, arg6_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
@ -344,6 +345,19 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
u32_t arg6_, \
void *ssf)
#define _SYSCALL_CONCAT(arg1, arg2) __SYSCALL_CONCAT(arg1, arg2)
#define __SYSCALL_CONCAT(arg1, arg2) ___SYSCALL_CONCAT(arg1, arg2)
#define ___SYSCALL_CONCAT(arg1, arg2) arg1##arg2
#define _SYSCALL_NARG(...) __SYSCALL_NARG(__VA_ARGS__, __SYSCALL_RSEQ_N())
#define __SYSCALL_NARG(...) __SYSCALL_ARG_N(__VA_ARGS__)
#define __SYSCALL_ARG_N(_1, _2, _3, _4, _5, _6, _7, N, ...) N
#define __SYSCALL_RSEQ_N() 6, 5, 4, 3, 2, 1, 0
#define _SYSCALL_HANDLER(...) \
_SYSCALL_CONCAT(__SYSCALL_HANDLER, \
_SYSCALL_NARG(__VA_ARGS__))(__VA_ARGS__)
/*
* Helper macros for a very common case: calls which just take one argument
* which is an initialized kernel object of a specific type. Verify the object
@ -351,25 +365,25 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
*/
#define _SYSCALL_HANDLER1_SIMPLE(name_, obj_enum_, obj_type_) \
_SYSCALL_HANDLER1(name_, arg1) { \
__SYSCALL_HANDLER1(name_, arg1) { \
_SYSCALL_OBJ(arg1, obj_enum_); \
return (u32_t)_impl_ ## name_((obj_type_)arg1); \
}
#define _SYSCALL_HANDLER1_SIMPLE_VOID(name_, obj_enum_, obj_type_) \
_SYSCALL_HANDLER1(name_, arg1) { \
__SYSCALL_HANDLER1(name_, arg1) { \
_SYSCALL_OBJ(arg1, obj_enum_); \
_impl_ ## name_((obj_type_)arg1); \
return 0; \
}
#define _SYSCALL_HANDLER0_SIMPLE(name_) \
_SYSCALL_HANDLER0(name_) { \
__SYSCALL_HANDLER0(name_) { \
return (u32_t)_impl_ ## name_(); \
}
#define _SYSCALL_HANDLER0_SIMPLE_VOID(name_) \
_SYSCALL_HANDLER0(name_) { \
__SYSCALL_HANDLER0(name_) { \
_impl_ ## name_(); \
return 0; \
}

View file

@ -64,7 +64,7 @@ void _impl_k_msgq_init(struct k_msgq *q, char *buffer,
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER4(k_msgq_init, q, buffer, msg_size, max_msgs)
_SYSCALL_HANDLER(k_msgq_init, q, buffer, msg_size, max_msgs)
{
_SYSCALL_OBJ_INIT(q, K_OBJ_MSGQ);
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, max_msgs, msg_size);
@ -124,7 +124,7 @@ int _impl_k_msgq_put(struct k_msgq *q, void *data, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER3(k_msgq_put, msgq_p, data, timeout)
_SYSCALL_HANDLER(k_msgq_put, msgq_p, data, timeout)
{
struct k_msgq *q = (struct k_msgq *)msgq_p;
@ -190,7 +190,7 @@ int _impl_k_msgq_get(struct k_msgq *q, void *data, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER3(k_msgq_get, msgq_p, data, timeout)
_SYSCALL_HANDLER(k_msgq_get, msgq_p, data, timeout)
{
struct k_msgq *q = (struct k_msgq *)msgq_p;

View file

@ -82,7 +82,7 @@ void _impl_k_mutex_init(struct k_mutex *mutex)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1(k_mutex_init, mutex)
_SYSCALL_HANDLER(k_mutex_init, mutex)
{
_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX);
_impl_k_mutex_init((struct k_mutex *)mutex);
@ -200,7 +200,7 @@ int _impl_k_mutex_lock(struct k_mutex *mutex, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER2(k_mutex_lock, mutex, timeout)
_SYSCALL_HANDLER(k_mutex_lock, mutex, timeout)
{
_SYSCALL_OBJ(mutex, K_OBJ_MUTEX);
return _impl_k_mutex_lock((struct k_mutex *)mutex, (s32_t)timeout);

View file

@ -141,7 +141,7 @@ void _impl_k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER3(k_pipe_init, pipe, buffer, size)
_SYSCALL_HANDLER(k_pipe_init, pipe, buffer, size)
{
_SYSCALL_OBJ_INIT(pipe, K_OBJ_PIPE);
_SYSCALL_MEMORY_WRITE(buffer, size);
@ -684,7 +684,7 @@ int _impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER6(k_pipe_get,
_SYSCALL_HANDLER(k_pipe_get,
pipe, data, bytes_to_read, bytes_read_p, min_xfer_p, timeout)
{
size_t *bytes_read = (size_t *)bytes_read_p;
@ -713,7 +713,7 @@ int _impl_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER6(k_pipe_put, pipe, data, bytes_to_write, bytes_written_p,
_SYSCALL_HANDLER(k_pipe_put, pipe, data, bytes_to_write, bytes_written_p,
min_xfer_p, timeout)
{
size_t *bytes_written = (size_t *)bytes_written_p;

View file

@ -285,7 +285,7 @@ void _impl_k_thread_priority_set(k_tid_t tid, int prio)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER2(k_thread_priority_set, thread_p, prio)
_SYSCALL_HANDLER(k_thread_priority_set, thread_p, prio)
{
struct k_thread *thread = (struct k_thread *)thread_p;
@ -380,7 +380,7 @@ void _impl_k_sleep(s32_t duration)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1(k_sleep, duration)
_SYSCALL_HANDLER(k_sleep, duration)
{
/* FIXME there were some discussions recently on whether we should
* relax this, thread would be unscheduled until k_wakeup issued

View file

@ -71,7 +71,7 @@ void _impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER3(k_sem_init, sem, initial_count, limit)
_SYSCALL_HANDLER(k_sem_init, sem, initial_count, limit)
{
_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM);
_SYSCALL_VERIFY(limit != 0);
@ -179,7 +179,7 @@ int _impl_k_sem_take(struct k_sem *sem, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER2(k_sem_take, sem, timeout)
_SYSCALL_HANDLER(k_sem_take, sem, timeout)
{
_SYSCALL_OBJ(sem, K_OBJ_SEM);
return _impl_k_sem_take((struct k_sem *)sem, timeout);

View file

@ -57,7 +57,7 @@ void _impl_k_stack_init(struct k_stack *stack, u32_t *buffer,
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER3(k_stack_init, stack, buffer, num_entries)
_SYSCALL_HANDLER(k_stack_init, stack, buffer, num_entries)
{
_SYSCALL_OBJ_INIT(stack, K_OBJ_STACK);
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, num_entries, sizeof(u32_t));
@ -99,7 +99,7 @@ void _impl_k_stack_push(struct k_stack *stack, u32_t data)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER2(k_stack_push, stack_p, data)
_SYSCALL_HANDLER(k_stack_push, stack_p, data)
{
struct k_stack *stack = (struct k_stack *)stack_p;
@ -140,7 +140,7 @@ int _impl_k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER3(k_stack_pop, stack, data, timeout)
_SYSCALL_HANDLER(k_stack_pop, stack, data, timeout)
{
_SYSCALL_OBJ(stack, K_OBJ_STACK);
_SYSCALL_MEMORY_WRITE(data, sizeof(u32_t));

View file

@ -79,7 +79,7 @@ u32_t _impl_k_uptime_get_32(void)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER0(k_uptime_get_32)
_SYSCALL_HANDLER(k_uptime_get_32)
{
#ifdef CONFIG_TICKLESS_KERNEL
_SYSCALL_VERIFY(_sys_clock_always_on);
@ -126,7 +126,7 @@ s64_t _impl_k_uptime_get(void)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1(k_uptime_get, ret_p)
_SYSCALL_HANDLER(k_uptime_get, ret_p)
{
u64_t *ret = (u64_t *)ret_p;

View file

@ -119,7 +119,7 @@ void _impl_k_thread_custom_data_set(void *value)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1(k_thread_custom_data_set, data)
_SYSCALL_HANDLER(k_thread_custom_data_set, data)
{
_impl_k_thread_custom_data_set((void *)data);
return 0;

View file

@ -47,7 +47,7 @@ void _impl_k_thread_abort(k_tid_t thread)
#endif
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1(k_thread_abort, thread_p)
_SYSCALL_HANDLER(k_thread_abort, thread_p)
{
struct k_thread *thread = (struct k_thread *)thread_p;
_SYSCALL_OBJ(thread, K_OBJ_THREAD);

View file

@ -132,7 +132,7 @@ void _impl_k_timer_start(struct k_timer *timer, s32_t duration, s32_t period)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER3(k_timer_start, timer, duration_p, period_p)
_SYSCALL_HANDLER(k_timer_start, timer, duration_p, period_p)
{
s32_t duration, period;
@ -259,7 +259,7 @@ s32_t _timeout_remaining_get(struct _timeout *timeout)
_SYSCALL_HANDLER1_SIMPLE(k_timer_remaining_get, K_OBJ_TIMER, struct k_timer *);
_SYSCALL_HANDLER1_SIMPLE(k_timer_user_data_get, K_OBJ_TIMER, struct k_timer *);
_SYSCALL_HANDLER2(k_timer_user_data_set, timer, user_data)
_SYSCALL_HANDLER(k_timer_user_data_set, timer, user_data)
{
_SYSCALL_OBJ(timer, K_OBJ_TIMER);
_impl_k_timer_user_data_set((struct k_timer *)timer, (void *)user_data);

View file

@ -35,7 +35,7 @@ static struct _k_object *validate_any_object(void *obj)
* To avoid double _k_object_find() lookups, we don't call the implementation
* function, but call a level deeper.
*/
_SYSCALL_HANDLER2(k_object_access_grant, object, thread)
_SYSCALL_HANDLER(k_object_access_grant, object, thread)
{
struct _k_object *ko;
@ -47,7 +47,7 @@ _SYSCALL_HANDLER2(k_object_access_grant, object, thread)
return 0;
}
_SYSCALL_HANDLER2(k_object_access_revoke, object, thread)
_SYSCALL_HANDLER(k_object_access_revoke, object, thread)
{
struct _k_object *ko;
@ -59,7 +59,7 @@ _SYSCALL_HANDLER2(k_object_access_revoke, object, thread)
return 0;
}
_SYSCALL_HANDLER1(k_object_access_all_grant, object)
_SYSCALL_HANDLER(k_object_access_all_grant, object)
{
struct _k_object *ko;

View file

@ -297,7 +297,7 @@ void _impl_k_str_out(char *c, size_t n)
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER2(k_str_out, c, n)
_SYSCALL_HANDLER(k_str_out, c, n)
{
_SYSCALL_MEMORY_READ(c, n);
_impl_k_str_out((char *)c, n);

View file

@ -7,7 +7,7 @@
#include <sensor.h>
#include <syscall_handler.h>
_SYSCALL_HANDLER4(sensor_attr_set, dev, chan, attr, val)
_SYSCALL_HANDLER(sensor_attr_set, dev, chan, attr, val)
{
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value));
@ -18,13 +18,13 @@ _SYSCALL_HANDLER4(sensor_attr_set, dev, chan, attr, val)
_SYSCALL_HANDLER1_SIMPLE(sensor_sample_fetch, K_OBJ_DRIVER_SENSOR,
struct device *);
_SYSCALL_HANDLER2(sensor_semple_fetch_chan, dev, type)
_SYSCALL_HANDLER(sensor_semple_fetch_chan, dev, type)
{
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
return _impl_sensor_sample_fetch_chan((struct device *)dev, type);
}
_SYSCALL_HANDLER3(sensor_channel_get, dev, chan, val)
_SYSCALL_HANDLER(sensor_channel_get, dev, chan, val)
{
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value));