#include "ipc/engine_message.h" #include #include atomic_flag handler_busy; void engine_message_handler_init(engine_message_handler_t *handle) { engine_message_t *message = calloc(sizeof(*message), 1); engine_message_init(message); handle->oldest_valid = message; handle->newest_valid = message; handle->count = 1; handle->pushed_count = 0; handle->popped_count = 0; } void engine_message_handler_deinit(engine_message_handler_t *handle) { engine_message_t *next, *message = handle->oldest_valid; int count = handle->count; while (count-- > 0) { next = message->next; engine_message_deinit(message); message = next; } } void engine_message_handler_acquire(engine_message_handler_t *handle) { while (atomic_flag_test_and_set(&handler_busy)); } void engine_message_handler_release(engine_message_handler_t *handle) { atomic_flag_clear(&handler_busy); } bool engine_message_handler_can_pop(engine_message_handler_t *handle) { assert(handle != NULL); engine_message_handler_acquire(handle); if (handle->count == 0) { engine_message_handler_release(handle); return false; } if (handle->oldest_valid == NULL) { printf("%d\n", handle->count); } bool output = engine_message_is_ready(handle->oldest_valid); engine_message_handler_release(handle); return output; } engine_message_t *engine_message_handler_pop( engine_message_handler_t *handle ) { assert(handle != NULL); engine_message_handler_acquire(handle); engine_message_t *output = handle->oldest_valid; handle->oldest_valid = handle->oldest_valid->next; handle->count--; handle->popped_count++; engine_message_handler_release(handle); return output; } engine_message_t *engine_message_handler_push( engine_message_handler_t *handle ) { assert(handle != NULL); engine_message_t *output = calloc(sizeof(*output), 1); engine_message_init(output); engine_message_handler_acquire(handle); if (handle->count > 0) { handle->newest_valid->next = output; } handle->newest_valid = output; if (handle->count == 0) { handle->oldest_valid = output; } handle->count++; handle->pushed_count++; engine_message_handler_release(handle); return output; } void engine_messages_init(engine_messages_t *messages) { assert(messages != NULL); // idc, i don't want to exceed 10 threads anyway messages->data = calloc(sizeof(*messages->data), 10); for (int i = 0; i < 10; i++) { messages->data[i] = malloc(sizeof(*messages->data[i])); engine_message_handler_init(messages->data[i]); } messages->count = 0; messages->capacity = 10; } void engine_messages_refresh(engine_messages_t *messages) { assert(messages != NULL); for (int i = 0; i < 10; i++) { messages->data[i] = malloc(sizeof(*messages->data[i])); engine_message_handler_init(messages->data[i]); } messages->count = 0; messages->capacity = 10; } void engine_message_mark_ready(engine_message_t *message) { atomic_store(&message->ready, 1); } bool engine_message_is_ready(engine_message_t *message) { return atomic_load(&message->ready) == 1; } void engine_messages_deinit(engine_messages_t *messages) { assert(messages != NULL); for (int i = 0; i < 10; i++) { engine_message_handler_deinit(messages->data[i]); free(messages->data[i]); } free(messages->data); } void engine_message_init(engine_message_t *message) { assert(message != NULL); message->ready = 0; ipc_moves_init(&message->pv); } void engine_message_deinit(engine_message_t *message) { assert(message != NULL); ipc_moves_deinit(&message->pv); free(message); }