From 75a16173ef6a590fa202dfa0dc05d07dfa463413 Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 14 Oct 2024 23:07:35 +0200 Subject: [PATCH] Mon 14 Oct 23:06:38 CEST 2024 --- kernel/event_queue.c | 108 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 kernel/event_queue.c diff --git a/kernel/event_queue.c b/kernel/event_queue.c new file mode 100644 index 0000000..22077a6 --- /dev/null +++ b/kernel/event_queue.c @@ -0,0 +1,108 @@ +#include "event_queue.h" +#include "interrupt.h" +#include "process.h" +#include "list.h" +#include "kmalloc.h" + +#define EVENT_BUFFER_SIZE 32 + +struct event_queue { + struct event buffer[EVENT_BUFFER_SIZE]; + struct list process_queue; + int head; + int tail; + int overflow_count; +}; + +struct event_queue event_queue_root; + +struct event_queue * event_queue_create_root() +{ + memset(&event_queue_root,0,sizeof(event_queue_root)); + return &event_queue_root; +} + +struct event_queue * event_queue_create() +{ + struct event_queue *q = kmalloc(sizeof(*q)); + memset(q,0,sizeof(*q)); + return q; +} + +void event_queue_delete( struct event_queue *q ) +{ + kfree(q); +} + +/* INTERRUPT CONTEXT */ + +void event_queue_post( struct event_queue *q, struct event *e ) +{ + /* If ring buffer is full, return immediately. */ + int next = (q->head+1) % EVENT_BUFFER_SIZE; + if(next==q->tail) { + q->overflow_count++; + return; + } + + /* Copy event to current buffer position */ + q->buffer[q->head] = *e; + + /* Advance head pointer and wake up waiting process (if any) */ + q->head = next; + process_wakeup(&q->process_queue); +} + +/* INTERRUPT CONTEXT */ + +void event_queue_post_root( uint16_t type, uint16_t code, int16_t x, int16_t y ) +{ + struct event e; + e.type = type; + e.code = code; + e.x = x; + e.y = y; + event_queue_post(&event_queue_root,&e); +} + +static int event_queue_read_raw( struct event_queue *q, struct event *e, int size, int blocking ) +{ + int total=0; + + if(size=sizeof(struct event)) { + + if(q->head==q->tail) { + if(blocking && total==0) { + process_wait(&q->process_queue); + continue; + } else { + break; + } + } + + *e = q->buffer[q->tail]; + q->tail = (q->tail+1) % EVENT_BUFFER_SIZE; + e++; + total++; + size -= sizeof(struct event); + } + + interrupt_unblock(); + + return total; +} + +int event_queue_read( struct event_queue *q, struct event *e, int size ) +{ + return event_queue_read_raw(q,e,size,1); +} + +int event_queue_read_nonblock( struct event_queue *q, struct event *e, int size ) +{ + return event_queue_read_raw(q,e,size,0); +} +