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

Brian Paul brianp at vmware.com
Wed Jan 22 09:00:13 PST 2014


On 01/21/2014 03:35 PM, Fredrik Höglund wrote:
> This patch adds functions for locking/unlocking the mutex, along with
> _mesa_HashLookupWithoutLocking() and _mesa_HashInsertWithoutLocking()
> 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.
> ---
>   src/mesa/main/hash.c |   90 ++++++++++++++++++++++++++++++++++++++++++++------
>   src/mesa/main/hash.h |    9 +++++
>   2 files changed, 89 insertions(+), 10 deletions(-)
>
> diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c
> index b31fd48..263397e 100644
> --- a/src/mesa/main/hash.c
> +++ b/src/mesa/main/hash.c
> @@ -150,7 +150,6 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table)
>   }
>
>
> -
>   /**
>    * Lookup an entry in the hash table, without locking.
>    * \sa _mesa_HashLookup
> @@ -195,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_HashLookupWithoutLocking(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);
> +   _glthread_LOCK_MUTEX(table->Mutex);
> +}
> +
> +
> +/**
> + * Unlock the hash table mutex.
> + *
> + * \param table the hash table.
> + */
> +void
> +_mesa_HashUnlockMutex(struct _mesa_HashTable *table)
> +{
> +   assert(table);
> +   _glthread_UNLOCK_MUTEX(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;
> @@ -211,8 +250,6 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
>      assert(table);
>      assert(key);
>
> -   _glthread_LOCK_MUTEX(table->Mutex);
> -
>      if (key > table->MaxKey)
>         table->MaxKey = key;
>
> @@ -226,11 +263,44 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
>            _mesa_hash_table_insert(table->ht, hash, uint_key(key), data);
>         }
>      }
> +}
>
> -   _glthread_UNLOCK_MUTEX(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_HashInsertWithoutLocking(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);
> +   _glthread_LOCK_MUTEX(table->Mutex);
> +   _mesa_HashInsert_unlocked(table, key, data);
> +   _glthread_UNLOCK_MUTEX(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..7ef8186 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_HashLookupWithoutLocking(struct _mesa_HashTable *table, GLuint key);
> +
> +extern void _mesa_HashInsertWithoutLocking(struct _mesa_HashTable *table,
> +                                           GLuint key, void *data);
> +
>   extern void
>   _mesa_HashDeleteAll(struct _mesa_HashTable *table,
>                       void (*callback)(GLuint key, void *data, void *userData),
>

In other parts of Mesa/gallium I believe we use function names such as 
FooLocked() to indicate that Foo should be called when the caller 
already holds the lock.

So, how about _mesa_HashLookupLocked(), etc?

Similar story for your new texobj.c and samplerobj.c functions in later 
patches.

-Brian



More information about the mesa-dev mailing list