Mesa (master): util/hash_table: Properly handle the NULL key in hash_table_u64

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 12 23:10:35 UTC 2019


Module: Mesa
Branch: master
Commit: eb41ce1b012f24fc7cba664dcc12129342e26843
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=eb41ce1b012f24fc7cba664dcc12129342e26843

Author: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
Date:   Mon Jun 10 12:10:54 2019 -0700

util/hash_table: Properly handle the NULL key in hash_table_u64

The hash_table_u64 should support any uint64_t as input.  It does
special handling for the "deleted" key, storing the data in the table
itself; do the same for the "freed" key.

Fixes: b38dab101ca "util/hash_table: Assert that keys are not reserved pointers"
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/util/hash_table.c | 41 ++++++++++++++++++++++++++++++++++++-----
 src/util/hash_table.h |  1 +
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/util/hash_table.c b/src/util/hash_table.c
index a764fabbf05..58104abd739 100644
--- a/src/util/hash_table.c
+++ b/src/util/hash_table.c
@@ -628,9 +628,12 @@ key_u64_equals(const void *a, const void *b)
    return aa->value == bb->value;
 }
 
+#define FREED_KEY_VALUE 0
+
 struct hash_table_u64 *
 _mesa_hash_table_u64_create(void *mem_ctx)
 {
+   STATIC_ASSERT(FREED_KEY_VALUE != DELETED_KEY_VALUE);
    struct hash_table_u64 *ht;
 
    ht = CALLOC_STRUCT(hash_table_u64);
@@ -661,18 +664,33 @@ _mesa_hash_table_u64_destroy(struct hash_table_u64 *ht,
    if (ht->deleted_key_data) {
       if (delete_function) {
          struct hash_table *table = ht->table;
-         struct hash_entry deleted_entry;
+         struct hash_entry entry;
 
          /* Create a fake entry for the delete function. */
-         deleted_entry.hash = table->key_hash_function(table->deleted_key);
-         deleted_entry.key = table->deleted_key;
-         deleted_entry.data = ht->deleted_key_data;
+         entry.hash = table->key_hash_function(table->deleted_key);
+         entry.key = table->deleted_key;
+         entry.data = ht->deleted_key_data;
 
-         delete_function(&deleted_entry);
+         delete_function(&entry);
       }
       ht->deleted_key_data = NULL;
    }
 
+   if (ht->freed_key_data) {
+      if (delete_function) {
+         struct hash_table *table = ht->table;
+         struct hash_entry entry;
+
+         /* Create a fake entry for the delete function. */
+         entry.hash = table->key_hash_function(uint_key(FREED_KEY_VALUE));
+         entry.key = uint_key(FREED_KEY_VALUE);
+         entry.data = ht->freed_key_data;
+
+         delete_function(&entry);
+      }
+      ht->freed_key_data = NULL;
+   }
+
    _mesa_hash_table_destroy(ht->table, delete_function);
    free(ht);
 }
@@ -681,6 +699,11 @@ void
 _mesa_hash_table_u64_insert(struct hash_table_u64 *ht, uint64_t key,
                             void *data)
 {
+   if (key == FREED_KEY_VALUE) {
+      ht->freed_key_data = data;
+      return;
+   }
+
    if (key == DELETED_KEY_VALUE) {
       ht->deleted_key_data = data;
       return;
@@ -715,6 +738,9 @@ _mesa_hash_table_u64_search(struct hash_table_u64 *ht, uint64_t key)
 {
    struct hash_entry *entry;
 
+   if (key == FREED_KEY_VALUE)
+      return ht->freed_key_data;
+
    if (key == DELETED_KEY_VALUE)
       return ht->deleted_key_data;
 
@@ -730,6 +756,11 @@ _mesa_hash_table_u64_remove(struct hash_table_u64 *ht, uint64_t key)
 {
    struct hash_entry *entry;
 
+   if (key == FREED_KEY_VALUE) {
+      ht->freed_key_data = NULL;
+      return;
+   }
+
    if (key == DELETED_KEY_VALUE) {
       ht->deleted_key_data = NULL;
       return;
diff --git a/src/util/hash_table.h b/src/util/hash_table.h
index c808a06d428..be7b50ff1fe 100644
--- a/src/util/hash_table.h
+++ b/src/util/hash_table.h
@@ -173,6 +173,7 @@ hash_table_call_foreach(struct hash_table *ht,
  */
 struct hash_table_u64 {
    struct hash_table *table;
+   void *freed_key_data;
    void *deleted_key_data;
 };
 




More information about the mesa-commit mailing list