1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #20916 from derMihai/mir/event_sync_mainline

sys/event: add event_sync()
This commit is contained in:
benpicco 2024-10-21 09:55:56 +00:00 committed by GitHub
commit c48247f984
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 3 deletions

View File

@ -27,6 +27,7 @@
#include "event.h"
#include "clist.h"
#include "mutex.h"
#include "thread.h"
#if IS_USED(MODULE_XTIMER)
@ -174,3 +175,27 @@ event_t *event_wait_timeout_ztimer(event_queue_t *queue,
return result;
}
#endif
typedef struct {
event_t ev;
mutex_t synced;
} sync_ev_t;
static void sync_ev_handler(event_t *ev)
{
sync_ev_t *sync_ev = (sync_ev_t *)ev;
mutex_unlock(&sync_ev->synced);
}
void event_sync(event_queue_t *queue)
{
/* if we're on the queue, this would block forever */
assert(!queue->waiter || queue->waiter->pid != thread_getpid());
sync_ev_t sync_ev = {
.ev.handler = sync_ev_handler,
.synced = MUTEX_INIT_LOCKED,
};
event_post(queue, &sync_ev.ev);
mutex_lock(&sync_ev.synced);
}

View File

@ -465,6 +465,27 @@ static inline void event_loop(event_queue_t *queue)
event_loop_multi(queue, 1);
}
/**
* @brief Synchronize with the last event on the queue
*
* Blocks until the last event on the queue at the moment of calling this is
* processed.
*
* @warning May not be called from the event queue, as it would block forever.
* @warning If the queue has no waiter, this will block until the queue is
* claimed. See @ref event_queue_claim()
*
* @param[in] queue event queue to sync with
*
* Usage example:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
* event_post(queue, my_event);
* // When event_sync() returns, my_event will have been processed.
* event_sync(queue);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
void event_sync(event_queue_t *queue);
#ifdef __cplusplus
}
#endif

View File

@ -35,7 +35,9 @@
#endif
#define STACKSIZE THREAD_STACKSIZE_DEFAULT
#define PRIO (THREAD_PRIORITY_MAIN - 1)
/* in order to actually test @ref event_sync(), the waiter's prio should be lower
* than main s.t. it doesn't start executing right after events are enqueued */
#define PRIO (THREAD_PRIORITY_MAIN + 1)
#define DELAYED_QUEUES_NUMOF 2
static char stack[STACKSIZE];
@ -164,6 +166,9 @@ int main(void)
event_queue_init_detached(&dqs[0]);
event_queue_init_detached(&dqs[1]);
printf("running thread that will claim event queues %p\n", (void *)&dqs);
thread_create(stack, sizeof(stack), PRIO, 0, claiming_thread, dqs, "ct");
printf("posting %p to delayed queue at index 1\n", (void *)&delayed_event1);
event_post(&dqs[1], &delayed_event1);
printf("posting %p to delayed queue at index 1\n", (void *)&delayed_event2);
@ -171,8 +176,9 @@ int main(void)
printf("posting %p to delayed queue at index 0\n", (void *)&delayed_event3);
event_post(&dqs[0], &delayed_event3);
printf("running thread that will claim event queues %p\n", (void *)&dqs);
thread_create(stack, sizeof(stack), PRIO, 0, claiming_thread, dqs, "ct");
event_sync(&dqs[1]);
expect(order == 3);
printf("synced with %p\n", (void *)&delayed_event3);
/* test posting different kind of events in order to a statically
* initialized queue */