kernel: event modification functions return previous value

Update the return value of functions that modify the internal event
state from `void` to `uint32_t`, so that calling code can determine
whether the event was already in a given state, or if the call modified
it.

This simplifies the usage of `struct k_event` as an alternative to
`atomic_t` that users can block on.

Implements #57216

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
Jordan Yates 2023-04-25 12:54:58 +10:00 committed by Carles Cufí
parent 3e33d6af89
commit 4ce1f03aa9
2 changed files with 33 additions and 21 deletions

View file

@ -2201,8 +2201,10 @@ __syscall void k_event_init(struct k_event *event);
*
* @param event Address of the event object
* @param events Set of events to post to @a event
*
* @retval Previous value of the events in @a event
*/
__syscall void k_event_post(struct k_event *event, uint32_t events);
__syscall uint32_t k_event_post(struct k_event *event, uint32_t events);
/**
* @brief Set the events in an event object
@ -2216,8 +2218,10 @@ __syscall void k_event_post(struct k_event *event, uint32_t events);
*
* @param event Address of the event object
* @param events Set of events to set in @a event
*
* @retval Previous value of the events in @a event
*/
__syscall void k_event_set(struct k_event *event, uint32_t events);
__syscall uint32_t k_event_set(struct k_event *event, uint32_t events);
/**
* @brief Set or clear the events in an event object
@ -2230,8 +2234,10 @@ __syscall void k_event_set(struct k_event *event, uint32_t events);
* @param event Address of the event object
* @param events Set of events to set/clear in @a event
* @param events_mask Mask to be applied to @a events
*
* @retval Previous value of the events in @a events_mask
*/
__syscall void k_event_set_masked(struct k_event *event, uint32_t events,
__syscall uint32_t k_event_set_masked(struct k_event *event, uint32_t events,
uint32_t events_mask);
/**
@ -2241,8 +2247,10 @@ __syscall void k_event_set_masked(struct k_event *event, uint32_t events,
*
* @param event Address of the event object
* @param events Set of events to clear in @a event
*
* @retval Previous value of the events in @a event
*/
__syscall void k_event_clear(struct k_event *event, uint32_t events);
__syscall uint32_t k_event_clear(struct k_event *event, uint32_t events);
/**
* @brief Wait for any of the specified events

View file

@ -119,12 +119,13 @@ static int event_walk_op(struct k_thread *thread, void *data)
return 0;
}
static void k_event_post_internal(struct k_event *event, uint32_t events,
static uint32_t k_event_post_internal(struct k_event *event, uint32_t events,
uint32_t events_mask)
{
k_spinlock_key_t key;
struct k_thread *thread;
struct event_walk_data data;
uint32_t previous_events;
data.head = NULL;
key = k_spin_lock(&event->lock);
@ -132,6 +133,7 @@ static void k_event_post_internal(struct k_event *event, uint32_t events,
SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_event, post, event, events,
events_mask);
previous_events = event->events & events_mask;
events = (event->events & ~events_mask) |
(events & events_mask);
event->events = events;
@ -164,62 +166,64 @@ static void k_event_post_internal(struct k_event *event, uint32_t events,
SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_event, post, event, events,
events_mask);
return previous_events;
}
void z_impl_k_event_post(struct k_event *event, uint32_t events)
uint32_t z_impl_k_event_post(struct k_event *event, uint32_t events)
{
k_event_post_internal(event, events, events);
return k_event_post_internal(event, events, events);
}
#ifdef CONFIG_USERSPACE
void z_vrfy_k_event_post(struct k_event *event, uint32_t events)
uint32_t z_vrfy_k_event_post(struct k_event *event, uint32_t events)
{
Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT));
z_impl_k_event_post(event, events);
return z_impl_k_event_post(event, events);
}
#include <syscalls/k_event_post_mrsh.c>
#endif
void z_impl_k_event_set(struct k_event *event, uint32_t events)
uint32_t z_impl_k_event_set(struct k_event *event, uint32_t events)
{
k_event_post_internal(event, events, ~0);
return k_event_post_internal(event, events, ~0);
}
#ifdef CONFIG_USERSPACE
void z_vrfy_k_event_set(struct k_event *event, uint32_t events)
uint32_t z_vrfy_k_event_set(struct k_event *event, uint32_t events)
{
Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT));
z_impl_k_event_set(event, events);
return z_impl_k_event_set(event, events);
}
#include <syscalls/k_event_set_mrsh.c>
#endif
void z_impl_k_event_set_masked(struct k_event *event, uint32_t events,
uint32_t z_impl_k_event_set_masked(struct k_event *event, uint32_t events,
uint32_t events_mask)
{
k_event_post_internal(event, events, events_mask);
return k_event_post_internal(event, events, events_mask);
}
#ifdef CONFIG_USERSPACE
void z_vrfy_k_event_set_masked(struct k_event *event, uint32_t events,
uint32_t z_vrfy_k_event_set_masked(struct k_event *event, uint32_t events,
uint32_t events_mask)
{
Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT));
z_impl_k_event_set_masked(event, events, events_mask);
return z_impl_k_event_set_masked(event, events, events_mask);
}
#include <syscalls/k_event_set_masked_mrsh.c>
#endif
void z_impl_k_event_clear(struct k_event *event, uint32_t events)
uint32_t z_impl_k_event_clear(struct k_event *event, uint32_t events)
{
k_event_post_internal(event, 0, events);
return k_event_post_internal(event, 0, events);
}
#ifdef CONFIG_USERSPACE
void z_vrfy_k_event_clear(struct k_event *event, uint32_t events)
uint32_t z_vrfy_k_event_clear(struct k_event *event, uint32_t events)
{
Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT));
z_impl_k_event_clear(event, events);
return z_impl_k_event_clear(event, events);
}
#include <syscalls/k_event_clear_mrsh.c>
#endif