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 <gert.wollny@collabora.com>
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36728>
This commit is contained in:
Marek Olšák 2025-08-11 00:25:55 -04:00 committed by Marge Bot
parent be5a15f11d
commit 2028caad28
3 changed files with 75 additions and 15 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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.