#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); }