From 67889a96852c7edf632349a096922f185aae6671 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Thu, 3 Dec 2020 15:39:59 +0100 Subject: [PATCH] cleanup event loop --- src/event_loop.c | 93 ++++++++++++++++++------------------------ src/event_loop.h | 16 ++------ src/misc/memory_pool.h | 3 +- 3 files changed, 44 insertions(+), 68 deletions(-) diff --git a/src/event_loop.c b/src/event_loop.c index fdc70373..a2fcdcce 100644 --- a/src/event_loop.c +++ b/src/event_loop.c @@ -1,54 +1,5 @@ #include "event_loop.h" -static inline bool queue_init(struct queue *queue) -{ - if (!memory_pool_init(&queue->pool, QUEUE_POOL_SIZE)) return false; - queue->head = memory_pool_push(&queue->pool, struct queue_item); - queue->head->data = NULL; - queue->head->next = NULL; - queue->tail = queue->head; - return true; -} - -static inline void queue_push(struct queue *queue, struct event *event) -{ - bool success; - struct queue_item *tail, *new_tail; - - new_tail = memory_pool_push(&queue->pool, struct queue_item); - new_tail->data = event; - new_tail->next = NULL; - __asm__ __volatile__ ("" ::: "memory"); - - do { - tail = queue->tail; - success = __sync_bool_compare_and_swap(&tail->next, NULL, new_tail); - } while (!success); - __sync_bool_compare_and_swap(&queue->tail, tail, new_tail); -} - -static inline struct event *queue_pop(struct queue *queue) -{ - struct queue_item *head; - - do { - head = queue->head; - if (!head->next) return NULL; - } while (!__sync_bool_compare_and_swap(&queue->head, head, head->next)); - - return head->next->data; -} - -static inline struct event *event_loop_create_event(struct event_loop *event_loop, enum event_type type, void *context, int param1, volatile uint32_t *info) -{ - struct event *event = memory_pool_push(&event_loop->pool, struct event); - event->type = type; - event->context = context; - event->param1 = param1; - event->info = info; - return event; -} - static inline void event_loop_destroy_event(struct event *event) { switch (event->type) { @@ -71,10 +22,18 @@ static inline void event_loop_destroy_event(struct event *event) static void *event_loop_run(void *context) { + struct queue_item *head; struct event_loop *event_loop = (struct event_loop *) context; + while (event_loop->is_running) { - struct event *event = queue_pop(&event_loop->queue); - if (event) { + do { + head = event_loop->head; + if (!head->next) break; + } while (!__sync_bool_compare_and_swap(&event_loop->head, head, head->next)); + + if (head->next && head->next->data) { + struct event *event = head->next->data; + uint32_t result = event_handler[event->type](event->context, event->param1); if (result == EVENT_SUCCESS) event_signal_transmit(event->context, event->type); @@ -95,17 +54,45 @@ static void *event_loop_run(void *context) void event_loop_post(struct event_loop *event_loop, enum event_type type, void *context, int param1, volatile uint32_t *info) { assert(event_loop->is_running); - queue_push(&event_loop->queue, event_loop_create_event(event_loop, type, context, param1, info)); + + bool success; + struct event *event; + struct queue_item *tail, *new_tail; + + new_tail = memory_pool_push(&event_loop->pool, sizeof(struct queue_item) + sizeof(struct event)); + new_tail->next = NULL; + new_tail->data = (void *)new_tail + sizeof(struct queue_item); + + event = new_tail->data; + event->type = type; + event->context = context; + event->param1 = param1; + event->info = info; + + __asm__ __volatile__ ("" ::: "memory"); + + do { + tail = event_loop->tail; + success = __sync_bool_compare_and_swap(&tail->next, NULL, new_tail); + } while (!success); + __sync_bool_compare_and_swap(&event_loop->tail, tail, new_tail); + sem_post(event_loop->semaphore); } bool event_loop_init(struct event_loop *event_loop) { - if (!queue_init(&event_loop->queue)) return false; if (!memory_pool_init(&event_loop->pool, EVENT_POOL_SIZE)) return false; + + event_loop->head = memory_pool_push(&event_loop->pool, sizeof(struct queue_item) + sizeof(struct event)); + event_loop->head->data = NULL; + event_loop->head->next = NULL; + event_loop->tail = event_loop->head; + event_loop->is_running = false; event_loop->semaphore = sem_open("yabai_event_loop_semaphore", O_CREAT, 0600, 0); sem_unlink("yabai_event_loop_semaphore"); + return event_loop->semaphore != SEM_FAILED; } diff --git a/src/event_loop.h b/src/event_loop.h index 2a2afc85..ba5870b2 100644 --- a/src/event_loop.h +++ b/src/event_loop.h @@ -1,11 +1,7 @@ #ifndef EVENT_LOOP_H #define EVENT_LOOP_H -#define EVENT_POOL_SIZE KILOBYTES(36) -#define EVENT_MAX_COUNT ((EVENT_POOL_SIZE) / (sizeof(struct event))) - -#define QUEUE_POOL_SIZE KILOBYTES(16) -#define QUEUE_MAX_COUNT ((QUEUE_POOL_SIZE) / (sizeof(struct queue_item))) +#define EVENT_POOL_SIZE KILOBYTES(128) struct queue_item { @@ -13,20 +9,14 @@ struct queue_item struct queue_item *next; }; -struct queue -{ - struct memory_pool pool; - struct queue_item *head; - struct queue_item *tail; -}; - struct event_loop { bool is_running; pthread_t thread; sem_t *semaphore; - struct queue queue; struct memory_pool pool; + struct queue_item *head; + struct queue_item *tail; }; bool event_loop_init(struct event_loop *event_loop); diff --git a/src/misc/memory_pool.h b/src/misc/memory_pool.h index f48f23a0..6dd1b287 100644 --- a/src/misc/memory_pool.h +++ b/src/misc/memory_pool.h @@ -16,8 +16,7 @@ bool memory_pool_init(struct memory_pool *pool, uint64_t size) return pool->memory != NULL; } -#define memory_pool_push(p, t) memory_pool_push_size(p, sizeof(t)) -void *memory_pool_push_size(struct memory_pool *pool, uint64_t size) +void *memory_pool_push(struct memory_pool *pool, uint64_t size) { for (;;) { uint64_t used = pool->used;