From 2de0c04b79a6c8e27bfab70e4378a606eb089553 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 29 Dec 2024 23:34:22 +0000 Subject: [PATCH] Experiment with different idea for allocating the event system --- src/event_system.c | 112 +++++++++++++++++++++++++++++++++++---------- src/event_system.h | 20 +++----- src/main.c | 2 +- 3 files changed, 97 insertions(+), 37 deletions(-) diff --git a/src/event_system.c b/src/event_system.c index 03a70f2..1c23e9c 100644 --- a/src/event_system.c +++ b/src/event_system.c @@ -1,15 +1,93 @@ #include "event_system.h" #include "aliases.h" #include +#include #include #include -#define INVALID_EVENT ((Event){ .id = 0 }) #define INVALID_LISTENER ((EventListener){ .event = INVALID_EVENT, .id = 0 }) - -#define IS_INVALID_EVENT(EV) (EV.id == 0) #define IS_INVALID_LISTENER(LS) (LS.id == 0) +struct event_system { + u64 alloc_size; + u64 event_capacity; + u64 event_count; + u64 free_count; + u64 initial_callback_capacity; + uptr events_offset; + uptr free_offset; + uptr callbacks_offset; +}; + +typedef struct event_slot EventSlot; +struct event_slot { + uptr offset; + bool free; +}; + +typedef struct event Event; +struct event { + u64 capacity; + u64 count; + EventCallback *callbacks[]; +}; + +void *alloc(u64 size); + +u32 es_init(EventSystem **es, u64 event_capacity, u64 initial_listeners_capacity) { + if (!es) { + return ES_INIT_NULL_POINTER; + } + + if (*es) { + return ES_INIT_ALREADY_INITIALISED; + } + + u64 callback_capacity = initial_listeners_capacity * 2; + u64 system = sizeof(EventSystem); + u64 event_slots = event_capacity * sizeof(EventSlot); + u64 free_slots = event_capacity * sizeof(u64); + u64 events = event_capacity * sizeof(Event); + u64 callbacks = event_capacity * callback_capacity * sizeof(EventCallback *); + u64 alloc_size = system + event_slots + free_slots + events + callbacks; + + u8 *buffer = alloc(alloc_size); + if (!buffer) { + return ES_INIT_ALLOCATION_FAILED; + } + + memset(buffer, 0, alloc_size); + + *es = (EventSystem *)buffer; + + EventSystem *event_system = *es; + + event_system->alloc_size = alloc_size; + event_system->event_capacity = event_capacity; + event_system->event_count = 0; + event_system->free_count = event_capacity; + event_system->initial_callback_capacity = callback_capacity; + event_system->events_offset = (uptr)system; + event_system->free_offset = (uptr)(system + event_slots); + event_system->callbacks_offset = (uptr)(system + event_slots + free_slots); + + EventSlot *ev_slots_ptr = (EventSlot *)((uptr)event_system + event_system->events_offset); + u64 *free_slots_ptr = (u64 *)((uptr)event_system + event_system->free_offset); + + u64 event_item_capacity = sizeof(Event) + callback_capacity * sizeof(EventCallback *); + for (u64 i = 0; i < event_capacity; ++i) { + free_slots_ptr[i] = event_capacity - (i + 1); + ev_slots_ptr[i].offset = event_system->callbacks_offset + i * event_item_capacity; + } + + return ES_INIT_SUCCESS; +} + +void *alloc(u64 size) { + return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_NORESERVE, -1, 0); +} + +#if 0 struct event_system { EventCallback *callbacks; u64 *callback_count; @@ -26,7 +104,7 @@ void default_init_event_system(EventSystem *es); bool is_default_initialised(const EventSystem *es); bool member_allocation_failed(const EventSystem *es); -u32 es_init(EventSystem **es, u64 initial_event_capacity, u64 max_event_listeners) { +u32 es_init(EventSystem **es, u64 event_capacity, u64 initial_listeners_capacity) { if (!es) { return ES_INIT_NULL_POINTER; } @@ -42,12 +120,10 @@ u32 es_init(EventSystem **es, u64 initial_event_capacity, u64 max_event_listener EventSystem *system = *es; - // Add extra event to account for keeping zero index free - u64 event_capacity = initial_event_capacity + 1; system->free_count = 0; system->event_count = 0; - system->event_capacity = initial_event_capacity; - system->max_listeners_count = max_event_listeners; + system->event_capacity = event_capacity; + system->max_listeners_count = initial_listeners_capacity; alloc_members(system, event_capacity); if (member_allocation_failed(system)) { @@ -76,26 +152,15 @@ void es_deinit(EventSystem **es) { *es = NULL; } -Event es_register_event(EventSystem *es) { - // TODO (Abdelrahman): Incomplete implementation - if (!es || is_default_initialised(es)) { - return INVALID_EVENT; - } +u32 es_register_event(EventSystem *es, u64 id) {} - return (Event){ .id = ++(es->event_count) }; -} +void es_deregister_event(EventSystem *es, u64 id) {} -void es_deregister_event(EventSystem *es, Event event) {} - -EventListener es_add_event_listener(EventSystem *es, Event event, EventCallback *listener) {} +EventListener es_add_event_listener(EventSystem *es, u64 id, EventCallback *listener) {} void es_remove_event_listener(EventSystem *es, EventListener listener) {} -void es_emit_event(EventSystem *es, Event event, void *data) {} - -void *alloc(u64 size) { - return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_NORESERVE, -1, 0); -} +void es_emit_event(EventSystem *es, u64 id, void *data) {} void alloc_members(EventSystem *es, u64 event_capacity) { es->callbacks = (EventCallback *)alloc(event_capacity * es->max_listeners_count * sizeof(EventCallback)); @@ -117,3 +182,4 @@ bool is_default_initialised(const EventSystem *es) { bool member_allocation_failed(const EventSystem *es) { return es->callbacks == NULL || es->callback_count == NULL || es->free == NULL; } +#endif diff --git a/src/event_system.h b/src/event_system.h index 680e613..5259c5a 100644 --- a/src/event_system.h +++ b/src/event_system.h @@ -6,18 +6,12 @@ enum { ES_INIT_SUCCESS = 0, ES_INIT_NULL_POINTER, ES_INIT_ALREADY_INITIALISED, - ES_INIT_SYSTEM_ALLOC_FAILED, - ES_INIT_MEMBER_ALLOC_FAILED, -}; - -typedef struct event Event; -struct event { - u64 id; + ES_INIT_ALLOCATION_FAILED, }; typedef struct event_listener EventListener; struct event_listener { - Event event; + u64 event; u64 id; }; @@ -25,10 +19,10 @@ typedef struct event_system EventSystem; typedef void (EventCallback)(void *data); -u32 es_init(EventSystem **es, u64 initial_event_capacity, u64 max_event_listeners); +u32 es_init(EventSystem **es, u64 event_capacity, u64 initial_event_listeners_count); void es_deinit(EventSystem **es); -Event es_register_event(EventSystem *es); -void es_deregister_event(EventSystem *es, Event event); -EventListener es_add_event_listener(EventSystem *es, Event event, EventCallback *listener); +u32 es_register_event(EventSystem *es, u64 id); +void es_deregister_event(EventSystem *es, u64 id); +EventListener es_add_event_listener(EventSystem *es, u64 id, EventCallback *listener); void es_remove_event_listener(EventSystem *es, EventListener listener); -void es_emit_event(EventSystem *es, Event event, void *data); +void es_emit_event(EventSystem *es, u64 id, void *data); diff --git a/src/main.c b/src/main.c index b647214..ede722d 100644 --- a/src/main.c +++ b/src/main.c @@ -9,7 +9,7 @@ int main(void) { return 1; } - es_deinit(&es); + // es_deinit(&es); return 0; }