[Mesa-dev] [PATCH 04/19] mesa: Add functions for doing unlocked hash table lookups

Fredrik Höglund fredrik at kde.org
Mon Apr 21 14:57:42 PDT 2014


This patch adds functions for locking/unlocking the mutex, along with
_mesa_HashLookupLocked() and _mesa_HashInsertLocked()
that do lookups and insertions without locking the mutex.

These functions will be used by the ARB_multi_bind entry points to
avoid locking/unlocking the mutex for each binding point.
---

v2: Name the new functions _mesa_Hash*Locked()

 src/mesa/main/hash.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++------
 src/mesa/main/hash.h |  9 ++++++
 2 files changed, 89 insertions(+), 9 deletions(-)

diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c
index 4c92005..23018e9 100644
--- a/src/mesa/main/hash.c
+++ b/src/mesa/main/hash.c
@@ -194,15 +194,55 @@ _mesa_HashLookup(struct _mesa_HashTable *table, GLuint key)
 
 
 /**
- * Insert a key/pointer pair into the hash table.  
- * If an entry with this key already exists we'll replace the existing entry.
- * 
+ * Lookup an entry in the hash table without locking the mutex.
+ *
+ * The hash table mutex must be locked manually by calling
+ * _mesa_HashLockMutex() before calling this function.
+ *
+ * \param table the hash table.
+ * \param key the key.
+ *
+ * \return pointer to user's data or NULL if key not in table
+ */
+void *
+_mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key)
+{
+   return _mesa_HashLookup_unlocked(table, key);
+}
+
+
+/**
+ * Lock the hash table mutex.
+ *
+ * This function should be used when multiple objects need
+ * to be looked up in the hash table, to avoid having to lock
+ * and unlock the mutex each time.
+ *
  * \param table the hash table.
- * \param key the key (not zero).
- * \param data pointer to user data.
  */
 void
-_mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
+_mesa_HashLockMutex(struct _mesa_HashTable *table)
+{
+   assert(table);
+   mtx_lock(&table->Mutex);
+}
+
+
+/**
+ * Unlock the hash table mutex.
+ *
+ * \param table the hash table.
+ */
+void
+_mesa_HashUnlockMutex(struct _mesa_HashTable *table)
+{
+   assert(table);
+   mtx_unlock(&table->Mutex);
+}
+
+
+static inline void
+_mesa_HashInsert_unlocked(struct _mesa_HashTable *table, GLuint key, void *data)
 {
    uint32_t hash = uint_hash(key);
    struct hash_entry *entry;
@@ -210,8 +250,6 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
    assert(table);
    assert(key);
 
-   mtx_lock(&table->Mutex);
-
    if (key > table->MaxKey)
       table->MaxKey = key;
 
@@ -225,11 +263,44 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
          _mesa_hash_table_insert(table->ht, hash, uint_key(key), data);
       }
    }
+}
 
-   mtx_unlock(&table->Mutex);
+
+/**
+ * Insert a key/pointer pair into the hash table without locking the mutex.
+ * If an entry with this key already exists we'll replace the existing entry.
+ *
+ * The hash table mutex must be locked manually by calling
+ * _mesa_HashLockMutex() before calling this function.
+ *
+ * \param table the hash table.
+ * \param key the key (not zero).
+ * \param data pointer to user data.
+ */
+void
+_mesa_HashInsertLocked(struct _mesa_HashTable *table, GLuint key, void *data)
+{
+   _mesa_HashInsert_unlocked(table, key, data);
 }
 
 
+/**
+ * Insert a key/pointer pair into the hash table.
+ * If an entry with this key already exists we'll replace the existing entry.
+ *
+ * \param table the hash table.
+ * \param key the key (not zero).
+ * \param data pointer to user data.
+ */
+void
+_mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
+{
+   assert(table);
+   mtx_lock(&table->Mutex);
+   _mesa_HashInsert_unlocked(table, key, data);
+   mtx_unlock(&table->Mutex);
+}
+
 
 /**
  * Remove an entry from the hash table.
diff --git a/src/mesa/main/hash.h b/src/mesa/main/hash.h
index b34f328..e3e8f49 100644
--- a/src/mesa/main/hash.h
+++ b/src/mesa/main/hash.h
@@ -45,6 +45,15 @@ extern void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *da
 
 extern void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key);
 
+extern void _mesa_HashLockMutex(struct _mesa_HashTable *table);
+
+extern void _mesa_HashUnlockMutex(struct _mesa_HashTable *table);
+
+extern void *_mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key);
+
+extern void _mesa_HashInsertLocked(struct _mesa_HashTable *table,
+                                   GLuint key, void *data);
+
 extern void
 _mesa_HashDeleteAll(struct _mesa_HashTable *table,
                     void (*callback)(GLuint key, void *data, void *userData),
-- 
1.8.5.3



More information about the mesa-dev mailing list