Mon 14 Oct 23:06:38 CEST 2024
This commit is contained in:
		
							parent
							
								
									39561050f8
								
							
						
					
					
						commit
						75a16173ef
					
				
							
								
								
									
										108
									
								
								kernel/event_queue.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								kernel/event_queue.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -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)) return KERROR_INVALID_REQUEST; | ||||||
|  | 
 | ||||||
|  | 	interrupt_block(); | ||||||
|  | 
 | ||||||
|  | 	while(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); | ||||||
|  | } | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user