Skip to content

Commit

Permalink
cleanup event loop
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed Dec 3, 2020
1 parent f0317d4 commit 67889a9
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 68 deletions.
93 changes: 40 additions & 53 deletions src/event_loop.c
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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);
Expand All @@ -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;
}

Expand Down
16 changes: 3 additions & 13 deletions src/event_loop.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
#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
{
struct event *data;
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);
Expand Down
3 changes: 1 addition & 2 deletions src/misc/memory_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 67889a9

Please sign in to comment.