/* * Copyright 2021 Google LLC * SPDX-License-Identifier: MIT */ #include "vn_renderer_util.h" void vn_renderer_shmem_pool_init(UNUSED struct vn_renderer *renderer, struct vn_renderer_shmem_pool *pool, size_t min_alloc_size) { *pool = (struct vn_renderer_shmem_pool){ /* power-of-two to hit shmem cache */ .min_alloc_size = util_next_power_of_two(min_alloc_size), }; mtx_init(&pool->mutex, mtx_plain); } void vn_renderer_shmem_pool_fini(struct vn_renderer *renderer, struct vn_renderer_shmem_pool *pool) { if (pool->shmem) vn_renderer_shmem_unref(renderer, pool->shmem); mtx_destroy(&pool->mutex); } static bool vn_renderer_shmem_pool_grow_locked(struct vn_renderer *renderer, struct vn_renderer_shmem_pool *pool, size_t size) { VN_TRACE_FUNC(); /* power-of-two to hit shmem cache */ size_t alloc_size = pool->min_alloc_size; while (alloc_size < size) { alloc_size <<= 1; if (!alloc_size) return false; } struct vn_renderer_shmem *shmem = vn_renderer_shmem_create(renderer, alloc_size); if (!shmem) return false; if (pool->shmem) vn_renderer_shmem_unref(renderer, pool->shmem); pool->shmem = shmem; pool->size = alloc_size; pool->used = 0; return true; } 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) { mtx_lock(&pool->mutex); if (unlikely(size > pool->size - pool->used)) { if (!vn_renderer_shmem_pool_grow_locked(renderer, pool, size)) { mtx_unlock(&pool->mutex); return NULL; } assert(size <= pool->size - pool->used); } struct vn_renderer_shmem *shmem = vn_renderer_shmem_ref(renderer, pool->shmem); *out_offset = pool->used; pool->used += size; mtx_unlock(&pool->mutex); return shmem; }