diff --git a/Makefile b/Makefile index a8a9483..4e56a84 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-g -O0 -std=c11 -fPIE -pedantic -Wall # -Werror +CFLAGS= -g -O0 -D _DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L -std=c11 -fPIE -pedantic -Wall # -Werror LDFLAGS=-lpthread -levdev CC=gcc OBJECTS=main.o input_dev.o output_dev.o queue.o @@ -15,4 +15,4 @@ depends: $(CC) -MM $(OBJECTS:.o=.c) > depends clean: - rm -f ./$(TARGET) *.o depends + rm -f ./$(TARGET) *.o depends \ No newline at end of file diff --git a/input_dev.h b/input_dev.h index 0305edc..e40cd88 100644 --- a/input_dev.h +++ b/input_dev.h @@ -1,6 +1,6 @@ #pragma once -#include "rogue_enemy.h" +#include "queue.h" #define INPUT_DEV_CTRL_FLAG_EXIT 0x00000001U @@ -24,6 +24,8 @@ typedef struct input_dev { const iio_filters_t* iio_filters; volatile uint32_t crtl_flags; + + queue_t *queue; } input_dev_t; void *input_dev_thread_func(void *ptr); diff --git a/main.c b/main.c index 49cdf8b..1308f24 100644 --- a/main.c +++ b/main.c @@ -3,8 +3,8 @@ #include "input_dev.h" #include "output_dev.h" -ev_queue_t imu_ev; -ev_queue_t gamepad_ev; +queue_t imu_ev; +queue_t gamepad_ev; static output_dev_t out_imu_dev = { .fd = -1, @@ -26,6 +26,7 @@ static input_dev_t in_asus_kb_1_dev = { .dev_type = input_dev_type_uinput, .crtl_flags = 0x00000000U, .ev_filters = &in_asus_kb_1_filters, + .queue = &gamepad_ev, }; static uinput_filters_t in_asus_kb_2_filters = { @@ -36,6 +37,7 @@ static input_dev_t in_asus_kb_2_dev = { .dev_type = input_dev_type_uinput, .crtl_flags = 0x00000000U, .ev_filters = &in_asus_kb_2_filters, + .queue = &gamepad_ev, }; static uinput_filters_t in_asus_kb_3_filters = { @@ -46,6 +48,7 @@ static input_dev_t in_asus_kb_3_dev = { .dev_type = input_dev_type_uinput, .crtl_flags = 0x00000000U, .ev_filters = &in_asus_kb_3_filters, + .queue = &gamepad_ev, }; static uinput_filters_t in_xbox_filters = { @@ -56,6 +59,7 @@ static input_dev_t in_xbox_dev = { .dev_type = input_dev_type_uinput, .crtl_flags = 0x00000000U, .ev_filters = &in_xbox_filters, + .queue = &gamepad_ev, }; void request_termination() { @@ -77,6 +81,9 @@ void sig_handler(int signo) } int main(int argc, char ** argv) { + queue_init(&gamepad_ev, 32); + queue_init(&imu_ev, 32); + out_imu_dev.fd = create_output_dev("/dev/uinput", "Virtual IMU - ROGueENEMY", output_dev_imu); if (out_imu_dev.fd < 0) { // TODO: free(imu_dev.events_list); @@ -94,11 +101,13 @@ int main(int argc, char ** argv) { return EXIT_FAILURE; } +/* __sighandler_t sigint_hndl = signal(SIGINT, sig_handler); if (sigint_hndl == SIG_ERR) { fprintf(stderr, "Error registering SIGINT handler\n"); return EXIT_FAILURE; } +*/ int ret = 0; diff --git a/output_dev.c b/output_dev.c index 8172def..fe4eb4d 100644 --- a/output_dev.c +++ b/output_dev.c @@ -1,4 +1,5 @@ #include "output_dev.h" +#include "queue.h" int create_output_dev(const char* uinput_path, const char* name, output_dev_type_t type) { int fd = open(uinput_path, O_WRONLY | O_NONBLOCK); @@ -150,6 +151,17 @@ void *output_dev_thread_func(void *ptr) { output_dev_t *out_dev = (output_dev_t*)ptr; for (;;) { + void *raw_ev; + const int pop_res = queue_pop_timeout(out_dev->queue, &raw_ev, 1000); + if (pop_res == 0) { + // do stuff + } else if (pop_res == -1) { + // timed out read + } else { + fprintf(stderr, "Cannot read from input queue: %d\n", pop_res); + continue; + } + const uint32_t flags = out_dev->crtl_flags; if (flags & OUTPUT_DEV_CTRL_FLAG_EXIT) { out_dev->crtl_flags &= ~OUTPUT_DEV_CTRL_FLAG_EXIT; diff --git a/output_dev.h b/output_dev.h index e116215..a9abdad 100644 --- a/output_dev.h +++ b/output_dev.h @@ -1,6 +1,5 @@ #pragma once -#include "rogue_enemy.h" #include "queue.h" #define OUTPUT_DEV_VENDOR_ID 0x4532 @@ -24,7 +23,7 @@ typedef struct output_dev { volatile uint32_t crtl_flags; - ev_queue_t *queue; + queue_t *queue; } output_dev_t; int create_output_dev(const char* uinput_path, const char* name, output_dev_type_t type); diff --git a/queue.c b/queue.c index b1ee40a..f48a031 100644 --- a/queue.c +++ b/queue.c @@ -1,67 +1,97 @@ #include "queue.h" #include -int queue_init(ev_queue_t* queue, key_t sem_key, size_t max_elements) { - queue->array_size = max_elements; - queue->array = calloc(sizeof(void*), max_elements); - if (queue->array == NULL) { +int queue_init(queue_t* const q, size_t max_elements) { + q->front = q->rear = -1; + q->array_size = max_elements; + q->array = calloc(sizeof(void*), max_elements); + if (q->array == NULL) { perror("calloc"); return -1; } - int semid = semget(sem_key, 1, IPC_CREAT | 0666); - if (semid < 0) - { - free(queue->array); - perror("semget"); - return 1; - } - - if (semctl(semid, 0, SETVAL, 1) < 0) - { - free(queue->array); - perror("semctl"); - return 1; - } + sem_init(&q->empty, 0, q->array_size); + sem_init(&q->full, 0, 0); + sem_init(&q->mutex, 0, 1); return 0; } -void queue_destroy(ev_queue_t* queue) { - free(queue->array); - queue->array = NULL; +void queue_destroy(queue_t* q) { + free(q->array); + q->array = NULL; } -int queue_push(ev_queue_t* queue, void *in_item) { - struct sembuf sem_op; - sem_op.sem_num = 0; - sem_op.sem_op = -1; - sem_op.sem_flg = 0; - semop(queue->sem_id, &sem_op, 1); +int queue_push(queue_t* const q, void *in_item) { + sem_wait(&q->empty); + sem_wait(&q->mutex); - queue->array[queue->in] = in_item; - queue->in = (queue->in + 1) % queue->array_size; + q->rear = (q->rear + 1) % q->array_size; + q->array[q->rear] = in_item; - sem_op.sem_num = 0; - sem_op.sem_op = 1; - semop(queue->sem_id, &sem_op, 1); + sem_post(&q->mutex); + sem_post(&q->full); return 0; } -int queue_pop(ev_queue_t* queue, void **out_item) { - struct sembuf sem_op; - sem_op.sem_num = 0; - sem_op.sem_op = -1; - sem_op.sem_flg = 0; - semop(queue->sem_id, &sem_op, 1); +int queue_pop(queue_t* const q, void **out_item) { + sem_wait(&q->full); + sem_wait(&q->mutex); - *out_item = queue->array[queue->out]; - queue->out = (queue->out + 1) % queue->array_size; + q->front = (q->front + 1) % q->array_size; + *out_item = q->array[q->front]; - sem_op.sem_num = 0; - sem_op.sem_op = 1; - semop(queue->sem_id, &sem_op, 1); + sem_post(&q->mutex); + sem_post(&q->empty); return 0; } + +int queue_push_timeout(queue_t* const q, void *in_item, int timeout_ms) { + struct timespec timeout; + if (clock_gettime(CLOCK_MONOTONIC, &timeout) == -1) { + // Handle clock_gettime error + return -1; + } + timeout.tv_sec += timeout_ms / 1000; + timeout.tv_nsec += (timeout_ms % 1000) * 1000000; + + int result = sem_timedwait(&q->empty, &timeout); + + if (result == 0) { + sem_wait(&q->mutex); + + q->rear = (q->rear + 1) % q->array_size; + q->array[q->rear] = in_item; + + sem_post(&q->mutex); + sem_post(&q->full); + } + + return result; +} + +int queue_pop_timeout(queue_t* const q, void **out_item, int timeout_ms) { + struct timespec timeout; + if (clock_gettime(CLOCK_MONOTONIC, &timeout) == -1) { + // Handle clock_gettime error + return -1; + } + timeout.tv_sec += timeout_ms / 1000; + timeout.tv_nsec += (timeout_ms % 1000) * 1000000; + + int result = sem_timedwait(&q->full, &timeout); + + if (result == 0) { + sem_wait(&q->mutex); + + q->front = (q->front + 1) % q->array_size; + *out_item = q->array[q->front]; + + sem_post(&q->mutex); + sem_post(&q->empty); + } + + return result; +} \ No newline at end of file diff --git a/queue.h b/queue.h index b5a1ee5..cdaa3b8 100644 --- a/queue.h +++ b/queue.h @@ -2,20 +2,24 @@ #include "rogue_enemy.h" -typedef struct ev_queue { - int sem_id; +typedef struct queue { + sem_t empty, full, mutex; - size_t in; - size_t out; + ssize_t front; + ssize_t rear; size_t array_size; void** array; -} ev_queue_t; +} queue_t; -int queue_init(ev_queue_t* queue, key_t sem_key, size_t max_elements); +int queue_init(queue_t* queue, size_t max_elements); -void queue_destroy(ev_queue_t* queue); +void queue_destroy(queue_t* queue); -int queue_push(ev_queue_t* queue, void *in_item); +int queue_push(queue_t* queue, void *in_item); -int queue_pop(ev_queue_t* queue, void **out_item); \ No newline at end of file +int queue_push_timeout(queue_t* const q, void *in_item, int timeout_ms); + +int queue_pop(queue_t* queue, void **out_item); + +int queue_pop_timeout(queue_t* const q, void **out_item, int timeout_ms); \ No newline at end of file diff --git a/rogue_enemy.h b/rogue_enemy.h index a02639f..85852df 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,8 @@ #include #include +#include + #include #include \ No newline at end of file