1 /*
2 * Copyright 2021 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "vn_renderer_util.h"
7
8 void
vn_renderer_shmem_pool_init(UNUSED struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool,size_t min_alloc_size)9 vn_renderer_shmem_pool_init(UNUSED struct vn_renderer *renderer,
10 struct vn_renderer_shmem_pool *pool,
11 size_t min_alloc_size)
12 {
13 *pool = (struct vn_renderer_shmem_pool){
14 /* power-of-two to hit shmem cache */
15 .min_alloc_size = util_next_power_of_two(min_alloc_size),
16 };
17 mtx_init(&pool->mutex, mtx_plain);
18 }
19
20 void
vn_renderer_shmem_pool_fini(struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool)21 vn_renderer_shmem_pool_fini(struct vn_renderer *renderer,
22 struct vn_renderer_shmem_pool *pool)
23 {
24 if (pool->shmem)
25 vn_renderer_shmem_unref(renderer, pool->shmem);
26 mtx_destroy(&pool->mutex);
27 }
28
29 static bool
vn_renderer_shmem_pool_grow_locked(struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool,size_t size)30 vn_renderer_shmem_pool_grow_locked(struct vn_renderer *renderer,
31 struct vn_renderer_shmem_pool *pool,
32 size_t size)
33 {
34 VN_TRACE_FUNC();
35 /* power-of-two to hit shmem cache */
36 size_t alloc_size = pool->min_alloc_size;
37 while (alloc_size < size) {
38 alloc_size <<= 1;
39 if (!alloc_size)
40 return false;
41 }
42
43 struct vn_renderer_shmem *shmem =
44 vn_renderer_shmem_create(renderer, alloc_size);
45 if (!shmem)
46 return false;
47
48 if (pool->shmem)
49 vn_renderer_shmem_unref(renderer, pool->shmem);
50
51 pool->shmem = shmem;
52 pool->size = alloc_size;
53 pool->used = 0;
54
55 return true;
56 }
57
58 struct vn_renderer_shmem *
vn_renderer_shmem_pool_alloc(struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool,size_t size,size_t * out_offset)59 vn_renderer_shmem_pool_alloc(struct vn_renderer *renderer,
60 struct vn_renderer_shmem_pool *pool,
61 size_t size,
62 size_t *out_offset)
63 {
64 mtx_lock(&pool->mutex);
65 if (unlikely(size > pool->size - pool->used)) {
66 if (!vn_renderer_shmem_pool_grow_locked(renderer, pool, size)) {
67 mtx_unlock(&pool->mutex);
68 return NULL;
69 }
70
71 assert(size <= pool->size - pool->used);
72 }
73
74 struct vn_renderer_shmem *shmem =
75 vn_renderer_shmem_ref(renderer, pool->shmem);
76 *out_offset = pool->used;
77 pool->used += size;
78 mtx_unlock(&pool->mutex);
79
80 return shmem;
81 }
82