1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker /**
26*61046927SAndroid Build Coastguard Worker * \file hash.h
27*61046927SAndroid Build Coastguard Worker * A table managing OpenGL object IDs.
28*61046927SAndroid Build Coastguard Worker */
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker #ifndef HASH_H
31*61046927SAndroid Build Coastguard Worker #define HASH_H
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
34*61046927SAndroid Build Coastguard Worker #include <stdint.h>
35*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker #include "c11/threads.h"
38*61046927SAndroid Build Coastguard Worker #include "util/simple_mtx.h"
39*61046927SAndroid Build Coastguard Worker #include "util/sparse_array.h"
40*61046927SAndroid Build Coastguard Worker #include "util/u_idalloc.h"
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker /**
43*61046927SAndroid Build Coastguard Worker * The not-really-hash-table data structure. It pretends to be a hash table,
44*61046927SAndroid Build Coastguard Worker * but it uses util_idalloc to keep track of GL object IDs and
45*61046927SAndroid Build Coastguard Worker * util_sparse_array for storing entries. Lookups only access the array.
46*61046927SAndroid Build Coastguard Worker */
47*61046927SAndroid Build Coastguard Worker struct _mesa_HashTable {
48*61046927SAndroid Build Coastguard Worker struct util_sparse_array array;
49*61046927SAndroid Build Coastguard Worker simple_mtx_t Mutex;
50*61046927SAndroid Build Coastguard Worker GLuint MaxKey; /**< highest key inserted so far */
51*61046927SAndroid Build Coastguard Worker bool alloc_via_idalloc;
52*61046927SAndroid Build Coastguard Worker /* Used when name reuse is enabled */
53*61046927SAndroid Build Coastguard Worker struct util_idalloc_sparse id_alloc;
54*61046927SAndroid Build Coastguard Worker };
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker void
57*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(struct _mesa_HashTable *table);
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker void
60*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(struct _mesa_HashTable *table,
61*61046927SAndroid Build Coastguard Worker void (*free_callback)(void *data, void *userData),
62*61046927SAndroid Build Coastguard Worker void *userData);
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker void
65*61046927SAndroid Build Coastguard Worker _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data);
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker void
68*61046927SAndroid Build Coastguard Worker _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key);
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker void
71*61046927SAndroid Build Coastguard Worker _mesa_HashInsertLocked(struct _mesa_HashTable *table, GLuint key, void *data);
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker void
74*61046927SAndroid Build Coastguard Worker _mesa_HashRemoveLocked(struct _mesa_HashTable *table, GLuint key);
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker void
77*61046927SAndroid Build Coastguard Worker _mesa_HashWalk(struct _mesa_HashTable *table,
78*61046927SAndroid Build Coastguard Worker void (*callback)(void *data, void *userData),
79*61046927SAndroid Build Coastguard Worker void *userData);
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker void
82*61046927SAndroid Build Coastguard Worker _mesa_HashWalkLocked(struct _mesa_HashTable *table,
83*61046927SAndroid Build Coastguard Worker void (*callback)(void *data, void *userData),
84*61046927SAndroid Build Coastguard Worker void *userData);
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker GLuint
87*61046927SAndroid Build Coastguard Worker _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys);
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker bool
90*61046927SAndroid Build Coastguard Worker _mesa_HashFindFreeKeys(struct _mesa_HashTable *table, GLuint* keys,
91*61046927SAndroid Build Coastguard Worker GLuint numKeys);
92*61046927SAndroid Build Coastguard Worker
93*61046927SAndroid Build Coastguard Worker void
94*61046927SAndroid Build Coastguard Worker _mesa_HashEnableNameReuse(struct _mesa_HashTable *table);
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker /* Inline functions. */
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker /**
99*61046927SAndroid Build Coastguard Worker * Lock the hash table mutex.
100*61046927SAndroid Build Coastguard Worker *
101*61046927SAndroid Build Coastguard Worker * This function should be used when multiple objects need
102*61046927SAndroid Build Coastguard Worker * to be looked up in the hash table, to avoid having to lock
103*61046927SAndroid Build Coastguard Worker * and unlock the mutex each time.
104*61046927SAndroid Build Coastguard Worker *
105*61046927SAndroid Build Coastguard Worker * \param table the hash table.
106*61046927SAndroid Build Coastguard Worker */
107*61046927SAndroid Build Coastguard Worker static inline void
_mesa_HashLockMutex(struct _mesa_HashTable * table)108*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(struct _mesa_HashTable *table)
109*61046927SAndroid Build Coastguard Worker {
110*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&table->Mutex);
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker /**
114*61046927SAndroid Build Coastguard Worker * Unlock the hash table mutex.
115*61046927SAndroid Build Coastguard Worker *
116*61046927SAndroid Build Coastguard Worker * \param table the hash table.
117*61046927SAndroid Build Coastguard Worker */
118*61046927SAndroid Build Coastguard Worker static inline void
_mesa_HashUnlockMutex(struct _mesa_HashTable * table)119*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(struct _mesa_HashTable *table)
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&table->Mutex);
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker static inline void
_mesa_HashLockMaybeLocked(struct _mesa_HashTable * table,bool locked)125*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(struct _mesa_HashTable *table, bool locked)
126*61046927SAndroid Build Coastguard Worker {
127*61046927SAndroid Build Coastguard Worker if (!locked)
128*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(table);
129*61046927SAndroid Build Coastguard Worker }
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker static inline void
_mesa_HashUnlockMaybeLocked(struct _mesa_HashTable * table,bool locked)132*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(struct _mesa_HashTable *table, bool locked)
133*61046927SAndroid Build Coastguard Worker {
134*61046927SAndroid Build Coastguard Worker if (!locked)
135*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(table);
136*61046927SAndroid Build Coastguard Worker }
137*61046927SAndroid Build Coastguard Worker
138*61046927SAndroid Build Coastguard Worker /**
139*61046927SAndroid Build Coastguard Worker * Lookup an entry in the hash table without locking the mutex.
140*61046927SAndroid Build Coastguard Worker *
141*61046927SAndroid Build Coastguard Worker * The hash table mutex must be locked manually by calling
142*61046927SAndroid Build Coastguard Worker * _mesa_HashLockMutex() before calling this function.
143*61046927SAndroid Build Coastguard Worker *
144*61046927SAndroid Build Coastguard Worker * \return pointer to user's data or NULL if key not in table
145*61046927SAndroid Build Coastguard Worker */
146*61046927SAndroid Build Coastguard Worker static inline void *
_mesa_HashLookupLocked(struct _mesa_HashTable * table,GLuint key)147*61046927SAndroid Build Coastguard Worker _mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key)
148*61046927SAndroid Build Coastguard Worker {
149*61046927SAndroid Build Coastguard Worker assert(key);
150*61046927SAndroid Build Coastguard Worker return *(void**)util_sparse_array_get(&table->array, key);
151*61046927SAndroid Build Coastguard Worker }
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker /**
154*61046927SAndroid Build Coastguard Worker * Lookup an entry in the hash table.
155*61046927SAndroid Build Coastguard Worker *
156*61046927SAndroid Build Coastguard Worker * \return pointer to user's data or NULL if key not in table
157*61046927SAndroid Build Coastguard Worker */
158*61046927SAndroid Build Coastguard Worker static inline void *
_mesa_HashLookup(struct _mesa_HashTable * table,GLuint key)159*61046927SAndroid Build Coastguard Worker _mesa_HashLookup(struct _mesa_HashTable *table, GLuint key)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(table);
162*61046927SAndroid Build Coastguard Worker void *res = _mesa_HashLookupLocked(table, key);
163*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(table);
164*61046927SAndroid Build Coastguard Worker return res;
165*61046927SAndroid Build Coastguard Worker }
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker static inline void *
_mesa_HashLookupMaybeLocked(struct _mesa_HashTable * table,GLuint key,bool locked)168*61046927SAndroid Build Coastguard Worker _mesa_HashLookupMaybeLocked(struct _mesa_HashTable *table, GLuint key,
169*61046927SAndroid Build Coastguard Worker bool locked)
170*61046927SAndroid Build Coastguard Worker {
171*61046927SAndroid Build Coastguard Worker if (locked)
172*61046927SAndroid Build Coastguard Worker return _mesa_HashLookupLocked(table, key);
173*61046927SAndroid Build Coastguard Worker else
174*61046927SAndroid Build Coastguard Worker return _mesa_HashLookup(table, key);
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Worker #endif
178