~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/util/disk_cache.h

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2014 Intel Corporation
3
 
 *
4
 
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 
 * copy of this software and associated documentation files (the "Software"),
6
 
 * to deal in the Software without restriction, including without limitation
7
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 
 * and/or sell copies of the Software, and to permit persons to whom the
9
 
 * Software is furnished to do so, subject to the following conditions:
10
 
 *
11
 
 * The above copyright notice and this permission notice (including the next
12
 
 * paragraph) shall be included in all copies or substantial portions of the
13
 
 * Software.
14
 
 *
15
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
 
 * IN THE SOFTWARE.
22
 
 */
23
 
 
24
 
#ifndef DISK_CACHE_H
25
 
#define DISK_CACHE_H
26
 
 
27
 
#ifdef HAVE_DLFCN_H
28
 
#include <dlfcn.h>
29
 
#include <stdio.h>
30
 
#include "util/build_id.h"
31
 
#endif
32
 
#include <assert.h>
33
 
#include <stdint.h>
34
 
#include <stdbool.h>
35
 
#include <sys/stat.h>
36
 
#include "util/mesa-sha1.h"
37
 
 
38
 
#ifdef __cplusplus
39
 
extern "C" {
40
 
#endif
41
 
 
42
 
/* Size of cache keys in bytes. */
43
 
#define CACHE_KEY_SIZE 20
44
 
 
45
 
#define CACHE_DIR_NAME "mesa_shader_cache"
46
 
#define CACHE_DIR_NAME_SF "mesa_shader_cache_sf"
47
 
 
48
 
typedef uint8_t cache_key[CACHE_KEY_SIZE];
49
 
 
50
 
/* WARNING: 3rd party applications might be reading the cache item metadata.
51
 
 * Do not change these values without making the change widely known.
52
 
 * Please contact Valve developers and make them aware of this change.
53
 
 */
54
 
#define CACHE_ITEM_TYPE_UNKNOWN  0x0
55
 
#define CACHE_ITEM_TYPE_GLSL     0x1
56
 
 
57
 
typedef void
58
 
(*disk_cache_put_cb) (const void *key, signed long keySize,
59
 
                      const void *value, signed long valueSize);
60
 
 
61
 
typedef signed long
62
 
(*disk_cache_get_cb) (const void *key, signed long keySize,
63
 
                      void *value, signed long valueSize);
64
 
 
65
 
struct cache_item_metadata {
66
 
   /**
67
 
    * The cache item type. This could be used to identify a GLSL cache item,
68
 
    * a certain type of IR (tgsi, nir, etc), or signal that it is the final
69
 
    * binary form of the shader.
70
 
    */
71
 
   uint32_t type;
72
 
 
73
 
   /** GLSL cache item metadata */
74
 
   cache_key *keys;   /* sha1 list of shaders that make up the cache item */
75
 
   uint32_t num_keys;
76
 
};
77
 
 
78
 
struct disk_cache;
79
 
 
80
 
static inline char *
81
 
disk_cache_format_hex_id(char *buf, const uint8_t *hex_id, unsigned size)
82
 
{
83
 
   static const char hex_digits[] = "0123456789abcdef";
84
 
   unsigned i;
85
 
 
86
 
   for (i = 0; i < size; i += 2) {
87
 
      buf[i] = hex_digits[hex_id[i >> 1] >> 4];
88
 
      buf[i + 1] = hex_digits[hex_id[i >> 1] & 0x0f];
89
 
   }
90
 
   buf[i] = '\0';
91
 
 
92
 
   return buf;
93
 
}
94
 
 
95
 
#ifdef HAVE_DLADDR
96
 
static inline bool
97
 
disk_cache_get_function_timestamp(void *ptr, uint32_t* timestamp)
98
 
{
99
 
   Dl_info info;
100
 
   struct stat st;
101
 
   if (!dladdr(ptr, &info) || !info.dli_fname) {
102
 
      return false;
103
 
   }
104
 
   if (stat(info.dli_fname, &st)) {
105
 
      return false;
106
 
   }
107
 
 
108
 
   if (!st.st_mtime) {
109
 
      fprintf(stderr, "Mesa: The provided filesystem timestamp for the cache "
110
 
              "is bogus! Disabling On-disk cache.\n");
111
 
      return false;
112
 
   }
113
 
 
114
 
   *timestamp = st.st_mtime;
115
 
 
116
 
   return true;
117
 
}
118
 
 
119
 
static inline bool
120
 
disk_cache_get_function_identifier(void *ptr, struct mesa_sha1 *ctx)
121
 
{
122
 
   uint32_t timestamp;
123
 
 
124
 
#ifdef HAVE_DL_ITERATE_PHDR
125
 
   const struct build_id_note *note = NULL;
126
 
   if ((note = build_id_find_nhdr_for_addr(ptr))) {
127
 
      _mesa_sha1_update(ctx, build_id_data(note), build_id_length(note));
128
 
   } else
129
 
#endif
130
 
   if (disk_cache_get_function_timestamp(ptr, &timestamp)) {
131
 
      _mesa_sha1_update(ctx, &timestamp, sizeof(timestamp));
132
 
   } else
133
 
      return false;
134
 
   return true;
135
 
}
136
 
#else
137
 
static inline bool
138
 
disk_cache_get_function_identifier(void *ptr, struct mesa_sha1 *ctx)
139
 
{
140
 
   return false;
141
 
}
142
 
#endif
143
 
 
144
 
/* Provide inlined stub functions if the shader cache is disabled. */
145
 
 
146
 
#ifdef ENABLE_SHADER_CACHE
147
 
 
148
 
/**
149
 
 * Create a new cache object.
150
 
 *
151
 
 * This function creates the handle necessary for all subsequent cache_*
152
 
 * functions.
153
 
 *
154
 
 * This cache provides two distinct operations:
155
 
 *
156
 
 *   o Storage and retrieval of arbitrary objects by cryptographic
157
 
 *     name (or "key").  This is provided via disk_cache_put() and
158
 
 *     disk_cache_get().
159
 
 *
160
 
 *   o The ability to store a key alone and check later whether the
161
 
 *     key was previously stored. This is provided via disk_cache_put_key()
162
 
 *     and disk_cache_has_key().
163
 
 *
164
 
 * The put_key()/has_key() operations are conceptually identical to
165
 
 * put()/get() with no data, but are provided separately to allow for
166
 
 * a more efficient implementation.
167
 
 *
168
 
 * In all cases, the keys are sequences of 20 bytes. It is anticipated
169
 
 * that callers will compute appropriate SHA-1 signatures for keys,
170
 
 * (though nothing in this implementation directly relies on how the
171
 
 * names are computed). See mesa-sha1.h and _mesa_sha1_compute for
172
 
 * assistance in computing SHA-1 signatures.
173
 
 */
174
 
struct disk_cache *
175
 
disk_cache_create(const char *gpu_name, const char *timestamp,
176
 
                  uint64_t driver_flags);
177
 
 
178
 
/**
179
 
 * Destroy a cache object, (freeing all associated resources).
180
 
 */
181
 
void
182
 
disk_cache_destroy(struct disk_cache *cache);
183
 
 
184
 
/* Wait for all previous disk_cache_put() calls to be processed (used for unit
185
 
 * testing).
186
 
 */
187
 
void
188
 
disk_cache_wait_for_idle(struct disk_cache *cache);
189
 
 
190
 
/**
191
 
 * Remove the item in the cache under the name \key.
192
 
 */
193
 
void
194
 
disk_cache_remove(struct disk_cache *cache, const cache_key key);
195
 
 
196
 
/**
197
 
 * Store an item in the cache under the name \key.
198
 
 *
199
 
 * The item can be retrieved later with disk_cache_get(), (unless the item has
200
 
 * been evicted in the interim).
201
 
 *
202
 
 * Any call to disk_cache_put() may cause an existing, random item to be
203
 
 * evicted from the cache.
204
 
 */
205
 
void
206
 
disk_cache_put(struct disk_cache *cache, const cache_key key,
207
 
               const void *data, size_t size,
208
 
               struct cache_item_metadata *cache_item_metadata);
209
 
 
210
 
/**
211
 
 * Store an item in the cache under the name \key without copying the data param.
212
 
 *
213
 
 * The item can be retrieved later with disk_cache_get(), (unless the item has
214
 
 * been evicted in the interim).
215
 
 *
216
 
 * Any call to disk_cache_put() may cause an existing, random item to be
217
 
 * evicted from the cache.
218
 
 *
219
 
 * @p data will be freed
220
 
 */
221
 
void
222
 
disk_cache_put_nocopy(struct disk_cache *cache, const cache_key key,
223
 
                      void *data, size_t size,
224
 
                      struct cache_item_metadata *cache_item_metadata);
225
 
 
226
 
/**
227
 
 * Retrieve an item previously stored in the cache with the name <key>.
228
 
 *
229
 
 * The item must have been previously stored with a call to disk_cache_put().
230
 
 *
231
 
 * If \size is non-NULL, then, on successful return, it will be set to the
232
 
 * size of the object.
233
 
 *
234
 
 * \return A pointer to the stored object if found. NULL if the object
235
 
 * is not found, or if any error occurs, (memory allocation failure,
236
 
 * filesystem error, etc.). The returned data is malloc'ed so the
237
 
 * caller should call free() it when finished.
238
 
 */
239
 
void *
240
 
disk_cache_get(struct disk_cache *cache, const cache_key key, size_t *size);
241
 
 
242
 
/**
243
 
 * Store the name \key within the cache, (without any associated data).
244
 
 *
245
 
 * Later this key can be checked with disk_cache_has_key(), (unless the key
246
 
 * has been evicted in the interim).
247
 
 *
248
 
 * Any call to disk_cache_put_key() may cause an existing, random key to be
249
 
 * evicted from the cache.
250
 
 */
251
 
void
252
 
disk_cache_put_key(struct disk_cache *cache, const cache_key key);
253
 
 
254
 
/**
255
 
 * Test whether the name \key was previously recorded in the cache.
256
 
 *
257
 
 * Return value: True if disk_cache_put_key() was previously called with
258
 
 * \key, (and the key was not evicted in the interim).
259
 
 *
260
 
 * Note: disk_cache_has_key() will only return true for keys passed to
261
 
 * disk_cache_put_key(). Specifically, a call to disk_cache_put() will not cause
262
 
 * disk_cache_has_key() to return true for the same key.
263
 
 */
264
 
bool
265
 
disk_cache_has_key(struct disk_cache *cache, const cache_key key);
266
 
 
267
 
/**
268
 
 * Compute the name \key from \data of given \size.
269
 
 */
270
 
void
271
 
disk_cache_compute_key(struct disk_cache *cache, const void *data, size_t size,
272
 
                       cache_key key);
273
 
 
274
 
void
275
 
disk_cache_set_callbacks(struct disk_cache *cache, disk_cache_put_cb put,
276
 
                         disk_cache_get_cb get);
277
 
 
278
 
#else
279
 
 
280
 
static inline struct disk_cache *
281
 
disk_cache_create(const char *gpu_name, const char *timestamp,
282
 
                  uint64_t driver_flags)
283
 
{
284
 
   return NULL;
285
 
}
286
 
 
287
 
static inline void
288
 
disk_cache_destroy(struct disk_cache *cache) {
289
 
   return;
290
 
}
291
 
 
292
 
static inline void
293
 
disk_cache_put(struct disk_cache *cache, const cache_key key,
294
 
               const void *data, size_t size,
295
 
               struct cache_item_metadata *cache_item_metadata)
296
 
{
297
 
   return;
298
 
}
299
 
 
300
 
static inline void
301
 
disk_cache_put_nocopy(struct disk_cache *cache, const cache_key key,
302
 
                      void *data, size_t size,
303
 
                      struct cache_item_metadata *cache_item_metadata)
304
 
{
305
 
   return;
306
 
}
307
 
 
308
 
static inline void
309
 
disk_cache_remove(struct disk_cache *cache, const cache_key key)
310
 
{
311
 
   return;
312
 
}
313
 
 
314
 
static inline uint8_t *
315
 
disk_cache_get(struct disk_cache *cache, const cache_key key, size_t *size)
316
 
{
317
 
   return NULL;
318
 
}
319
 
 
320
 
static inline void
321
 
disk_cache_put_key(struct disk_cache *cache, const cache_key key)
322
 
{
323
 
   return;
324
 
}
325
 
 
326
 
static inline bool
327
 
disk_cache_has_key(struct disk_cache *cache, const cache_key key)
328
 
{
329
 
   return false;
330
 
}
331
 
 
332
 
static inline void
333
 
disk_cache_compute_key(struct disk_cache *cache, const void *data, size_t size,
334
 
                       const cache_key key)
335
 
{
336
 
   return;
337
 
}
338
 
 
339
 
static inline void
340
 
disk_cache_set_callbacks(struct disk_cache *cache, disk_cache_put_cb put,
341
 
                         disk_cache_get_cb get)
342
 
{
343
 
   return;
344
 
}
345
 
 
346
 
#endif /* ENABLE_SHADER_CACHE */
347
 
 
348
 
#ifdef __cplusplus
349
 
}
350
 
#endif
351
 
 
352
 
#endif /* CACHE_H */