diff --git a/components/retro-go/rg_gui.c b/components/retro-go/rg_gui.c index df645b43..1dec0e19 100644 --- a/components/retro-go/rg_gui.c +++ b/components/retro-go/rg_gui.c @@ -1066,7 +1066,7 @@ char *rg_gui_file_picker(const char *title, const char *path, bool (*validator)( file_picker_opts_t options = { .options = calloc(8, sizeof(rg_gui_option_t)), .count = 0, - .filenames = rg_bucket_create(4096, 1), + .filenames = rg_bucket_create(4096), .validator = validator, }; char *filepath = NULL; diff --git a/components/retro-go/rg_utils.c b/components/retro-go/rg_utils.c index c354a5b2..73ca46b7 100644 --- a/components/retro-go/rg_utils.c +++ b/components/retro-go/rg_utils.c @@ -355,19 +355,17 @@ typedef struct rg_bucket_s { size_t capacity; size_t cursor; - size_t alignment; rg_bucket_t *prev; rg_bucket_t *next; uint8_t data[]; } rg_bucket_t; -rg_bucket_t *rg_bucket_create(size_t capacity_bytes, size_t alignment_bytes) +rg_bucket_t *rg_bucket_create(size_t capacity_bytes) { rg_bucket_t *bucket = calloc(1, sizeof(rg_bucket_t) + capacity_bytes); if (!bucket) return NULL; bucket->capacity = capacity_bytes; - bucket->alignment = alignment_bytes ?: 1; return bucket; } @@ -382,7 +380,7 @@ void *rg_bucket_insert(rg_bucket_t *bucket, const void *item, size_t item_bytes) { if (!bucket->next) // End of the list, must allocate { - rg_bucket_t *new_bucket = rg_bucket_create(bucket->capacity, bucket->alignment); + rg_bucket_t *new_bucket = rg_bucket_create(bucket->capacity); if (!new_bucket) return NULL; new_bucket->prev = bucket; @@ -392,9 +390,11 @@ void *rg_bucket_insert(rg_bucket_t *bucket, const void *item, size_t item_bytes) } bucket = bucket->next; } - void *ptr = memcpy(bucket->data + bucket->cursor, item, item_bytes); - bucket->cursor += item_bytes; - bucket->cursor += bucket->cursor % bucket->alignment; + void *ptr = bucket->data + bucket->cursor; + if (item) + memcpy(ptr, item, item_bytes); + bucket->cursor += ((item_bytes + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int); + // bucket->cursor += item_bytes; return ptr; } @@ -408,9 +408,6 @@ void rg_bucket_free(rg_bucket_t *bucket) } } -// Note: You should use calloc/malloc everywhere possible. This function is used to ensure -// that some memory is put in specific regions for performance or hardware reasons. -// Memory from this function should be freed with free() void *rg_alloc(size_t size, uint32_t caps) { char caps_list[36] = ""; diff --git a/components/retro-go/rg_utils.h b/components/retro-go/rg_utils.h index 16ac9101..d1f77718 100644 --- a/components/retro-go/rg_utils.h +++ b/components/retro-go/rg_utils.h @@ -47,7 +47,6 @@ * they cannot be freed. unique avoids keeping multiple copies of an identical string (eg a path) * Things like unique_string("abc") == unique_string("abc") are guaranteed to be true */ -const char *rg_const_string(const char *str); const char *rg_unique_string(const char *str); char *rg_strtolower(char *str); char *rg_strtoupper(char *str); @@ -74,14 +73,18 @@ uint32_t rg_crc32(uint32_t crc, const uint8_t *buf, size_t len); uint32_t rg_hash(const char *buf, size_t len); /* Bucket allocator */ -// The bucket allocator is basically a linked-list of buckets. It's not smart in any way and can only grow. -// Its purpose is to replace thousands of small allocations that fill internal memory (eg strdup) +// The bucket allocator is basically a linked-list of fixed-size buckets that can contain variable-sized items. +// It does not keep track of individual items and items cannot be removed or resized. +// Its purpose is to replace the thousands of small allocations that fill internal memory (eg strdup) typedef struct rg_bucket_s rg_bucket_t; -rg_bucket_t *rg_bucket_create(size_t capacity_bytes, size_t alignment_bytes); +rg_bucket_t *rg_bucket_create(size_t capacity_bytes); void *rg_bucket_insert(rg_bucket_t *bucket, const void *item, size_t item_bytes); void rg_bucket_free(rg_bucket_t *bucket); /* Misc */ +// Note: You should use calloc/malloc everywhere possible. This function is used to ensure +// that some memory is put in specific regions for performance or hardware reasons. +// Memory from this function should be freed with free() void *rg_alloc(size_t size, uint32_t caps); // rg_usleep behaves like usleep in libc: it will sleep for *at least* `us` microseconds, but possibly more // due to scheduling. You should use rg_task_delay() if you don't need more than 10-15ms granularity. diff --git a/launcher/main/applications.c b/launcher/main/applications.c index 9c0d8ccb..6af4768c 100644 --- a/launcher/main/applications.c +++ b/launcher/main/applications.c @@ -430,7 +430,7 @@ static void event_handler(gui_event_t event, tab_t *tab) if (app && app->initialized) { rg_bucket_free(app->filenames); - app->filenames = rg_bucket_create(4096, 1); + app->filenames = rg_bucket_create(4096); app->files_count = 0; app->initialized = false; } @@ -681,7 +681,7 @@ static void application(const char *desc, const char *name, const char *exts, co app->available = rg_system_have_app(app->partition); app->files = calloc(100, sizeof(retro_file_t)); app->files_capacity = 100; - app->filenames = rg_bucket_create(4096, 1); + app->filenames = rg_bucket_create(4096); app->crc_offset = crc_offset; gui_add_tab(app->short_name, app->description, app, event_handler);