From 2028caad28b6d65666029292bfdc6021b3dc3382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 11 Aug 2025 00:25:55 -0400 Subject: [PATCH] util/hash_table: improve support for usage without "hash_table" allocation _mesa_hash_table_init & _mesa_hash_table_fini (and equivalents) is the preferred way to set up hash tables. This adds missing "init" and "fini" functions. _mesa_string_hash_table_create is also changed to non-inline. Reviewed-by: Gert Wollny Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/frontends/lavapipe/lvp_device.c | 2 +- src/util/hash_table.c | 58 ++++++++++++++++++--- src/util/hash_table.h | 30 ++++++++--- 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index ea861e7bdd9..7e1d7f7fba8 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -1870,7 +1870,7 @@ VKAPI_ATTR void VKAPI_CALL lvp_DestroyDevice( if (device->queue.last_fence) device->pscreen->fence_reference(device->pscreen, &device->queue.last_fence, NULL); - ralloc_free(device->bda.table); + _mesa_hash_table_fini(&device->bda, NULL); simple_mtx_destroy(&device->bda_lock); pipe_resource_reference(&device->zero_buffer, NULL); diff --git a/src/util/hash_table.c b/src/util/hash_table.c index 58a0bf2e2e2..5545190f514 100644 --- a/src/util/hash_table.c +++ b/src/util/hash_table.c @@ -183,6 +183,7 @@ _mesa_hash_table_init(struct hash_table *ht, return ht->table != NULL; } +/* It's preferred to use _mesa_hash_table_init instead of this to skip ralloc. */ struct hash_table * _mesa_hash_table_create(void *mem_ctx, uint32_t (*key_hash_function)(const void *key), @@ -220,12 +221,19 @@ key_u32_equals(const void *a, const void *b) } /* key == 0 and key == deleted_key are not allowed */ +/* It's preferred to use _mesa_hash_table_init_u32_keys instead of this to skip ralloc. */ struct hash_table * _mesa_hash_table_create_u32_keys(void *mem_ctx) { return _mesa_hash_table_create(mem_ctx, key_u32_hash, key_u32_equals); } +bool +_mesa_hash_table_init_u32_keys(struct hash_table *ht, void *mem_ctx) +{ + return _mesa_hash_table_init(ht, mem_ctx, key_u32_hash, key_u32_equals); +} + struct hash_table * _mesa_hash_table_clone(struct hash_table *src, void *dst_mem_ctx) { @@ -248,6 +256,26 @@ _mesa_hash_table_clone(struct hash_table *src, void *dst_mem_ctx) return ht; } +/** + * Deallocates the internal table. This is optional and doesn't need to be + * called when: + * - you don't need to call delete_function + * - the initial ralloc context is non-NULL, meaning it gets freed + * automatically when the ralloc parent is freed. + */ +void +_mesa_hash_table_fini(struct hash_table *ht, + void (*delete_function)(struct hash_entry *entry)) +{ + if (delete_function) { + hash_table_foreach(ht, entry) { + delete_function(entry); + } + } + ralloc_free(ht->table); + ht->table = NULL; +} + /** * Frees the given hash table. * @@ -261,11 +289,7 @@ _mesa_hash_table_destroy(struct hash_table *ht, if (!ht) return; - if (delete_function) { - hash_table_foreach(ht, entry) { - delete_function(entry); - } - } + _mesa_hash_table_fini(ht, delete_function); ralloc_free(ht); } @@ -738,7 +762,7 @@ _mesa_key_u64_equal(const void *a, const void *b) /** * String compare function for use as the comparison callback in - * _mesa_hash_table_create(). + * _mesa_hash_table_create() and _mesa_hash_table_init(). */ bool _mesa_key_string_equal(const void *a, const void *b) @@ -753,6 +777,7 @@ _mesa_key_pointer_equal(const void *a, const void *b) } /** + * It's preferred to use _mesa_pointer_hash_table_init instead of this to skip ralloc. * Helper to create a hash table with pointer keys. */ struct hash_table * @@ -762,6 +787,27 @@ _mesa_pointer_hash_table_create(void *mem_ctx) _mesa_key_pointer_equal); } +bool +_mesa_pointer_hash_table_init(struct hash_table *ht, void *mem_ctx) +{ + return _mesa_hash_table_init(ht, mem_ctx, _mesa_hash_pointer, + _mesa_key_pointer_equal); +} + +/* It's preferred to use _mesa_string_hash_table_init instead of this to skip ralloc. */ +struct hash_table * +_mesa_string_hash_table_create(void *mem_ctx) +{ + return _mesa_hash_table_create(mem_ctx, _mesa_hash_string, + _mesa_key_string_equal); +} + +bool +_mesa_string_hash_table_init(struct hash_table *ht, void *mem_ctx) +{ + return _mesa_hash_table_init(ht, mem_ctx, _mesa_hash_string, + _mesa_key_string_equal); +} bool _mesa_hash_table_reserve(struct hash_table *ht, unsigned size) diff --git a/src/util/hash_table.h b/src/util/hash_table.h index 928f3db7d0d..f4bbc526c7b 100644 --- a/src/util/hash_table.h +++ b/src/util/hash_table.h @@ -71,9 +71,16 @@ _mesa_hash_table_init(struct hash_table *ht, bool (*key_equals_function)(const void *a, const void *b)); +void +_mesa_hash_table_fini(struct hash_table *ht, + void (*delete_function)(struct hash_entry *entry)); + struct hash_table * _mesa_hash_table_create_u32_keys(void *mem_ctx); +bool +_mesa_hash_table_init_u32_keys(struct hash_table *ht, void *mem_ctx); + struct hash_table * _mesa_hash_table_clone(struct hash_table *src, void *dst_mem_ctx); void _mesa_hash_table_destroy(struct hash_table *ht, @@ -132,12 +139,14 @@ bool _mesa_key_pointer_equal(const void *a, const void *b); struct hash_table * _mesa_pointer_hash_table_create(void *mem_ctx); -static inline struct hash_table * -_mesa_string_hash_table_create(void *mem_ctx) -{ - return _mesa_hash_table_create(mem_ctx, _mesa_hash_string, - _mesa_key_string_equal); -} +bool +_mesa_pointer_hash_table_init(struct hash_table *ht, void *mem_ctx); + +struct hash_table * +_mesa_string_hash_table_create(void *mem_ctx); + +bool +_mesa_string_hash_table_init(struct hash_table *ht, void *mem_ctx); bool _mesa_hash_table_reserve(struct hash_table *ht, unsigned size); @@ -186,10 +195,15 @@ hash_table_call_foreach(struct hash_table *ht, return memcmp(a, b, sizeof(struct T)) == 0; \ } \ \ - static struct hash_table *T##_table_create(void *memctx) \ + static UNUSED inline struct hash_table *T##_table_create(void *memctx) \ { \ return _mesa_hash_table_create(memctx, T##_hash, T##_equal); \ - } + } \ + \ + static UNUSED inline bool T##_table_init(struct hash_table *ht, void *memctx) \ + { \ + return _mesa_hash_table_init(ht, memctx, T##_hash, T##_equal); \ + } \ /** * Hash table wrapper which supports 64-bit keys.