From 175549e0e988d10f8277c30ae4e6b6d5fea702a4 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 1 Jan 2018 22:47:36 +0100 Subject: pb_cache: let drivers choose the number of buckets Reviewed-by: Samuel Pitoiset --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_cache.c | 23 ++++++++++++++++++---- src/gallium/auxiliary/pipebuffer/pb_cache.h | 6 ++++-- 3 files changed, 24 insertions(+), 7 deletions(-) (limited to 'src/gallium/auxiliary') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 24831f60948..4e70048cd83 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -304,7 +304,7 @@ pb_cache_manager_create(struct pb_manager *provider, mgr->base.create_buffer = pb_cache_manager_create_buffer; mgr->base.flush = pb_cache_manager_flush; mgr->provider = provider; - pb_cache_init(&mgr->cache, usecs, size_factor, bypass_usage, + pb_cache_init(&mgr->cache, 1, usecs, size_factor, bypass_usage, maximum_cache_size, _pb_cache_buffer_destroy, pb_cache_can_reclaim_buffer); diff --git a/src/gallium/auxiliary/pipebuffer/pb_cache.c b/src/gallium/auxiliary/pipebuffer/pb_cache.c index dd479ae7719..0aaedbfae4c 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_cache.c @@ -92,7 +92,7 @@ pb_cache_add_buffer(struct pb_cache_entry *entry) int64_t current_time = os_time_get(); - for (i = 0; i < ARRAY_SIZE(mgr->buckets); i++) + for (i = 0; i < mgr->num_heaps; i++) release_expired_buffers_locked(&mgr->buckets[i], current_time); /* Directly release any buffer that exceeds the limit. */ @@ -153,6 +153,8 @@ pb_cache_reclaim_buffer(struct pb_cache *mgr, pb_size size, struct list_head *cur, *next; int64_t now; int ret = 0; + + assert(bucket_index < mgr->num_heaps); struct list_head *cache = &mgr->buckets[bucket_index]; mtx_lock(&mgr->mutex); @@ -229,7 +231,7 @@ pb_cache_release_all_buffers(struct pb_cache *mgr) unsigned i; mtx_lock(&mgr->mutex); - for (i = 0; i < ARRAY_SIZE(mgr->buckets); i++) { + for (i = 0; i < mgr->num_heaps; i++) { struct list_head *cache = &mgr->buckets[i]; curr = cache->next; @@ -248,6 +250,8 @@ void pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry, struct pb_buffer *buf, unsigned bucket_index) { + assert(bucket_index < mgr->num_heaps); + memset(entry, 0, sizeof(*entry)); entry->buffer = buf; entry->mgr = mgr; @@ -258,6 +262,9 @@ pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry, * Initialize a caching buffer manager. * * @param mgr The cache buffer manager + * @param num_heaps Number of separate caches/buckets indexed by bucket_index + * for faster buffer matching (alternative to slower + * "usage"-based matching). * @param usecs Unused buffers may be released from the cache after this * time * @param size_factor Declare buffers that are size_factor times bigger than @@ -270,19 +277,25 @@ pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry, * @param can_reclaim Whether a buffer can be reclaimed (e.g. is not busy) */ void -pb_cache_init(struct pb_cache *mgr, uint usecs, float size_factor, +pb_cache_init(struct pb_cache *mgr, uint num_heaps, + uint usecs, float size_factor, unsigned bypass_usage, uint64_t maximum_cache_size, void (*destroy_buffer)(struct pb_buffer *buf), bool (*can_reclaim)(struct pb_buffer *buf)) { unsigned i; - for (i = 0; i < ARRAY_SIZE(mgr->buckets); i++) + mgr->buckets = CALLOC(num_heaps, sizeof(struct list_head)); + if (!mgr->buckets) + return; + + for (i = 0; i < num_heaps; i++) LIST_INITHEAD(&mgr->buckets[i]); (void) mtx_init(&mgr->mutex, mtx_plain); mgr->cache_size = 0; mgr->max_cache_size = maximum_cache_size; + mgr->num_heaps = num_heaps; mgr->usecs = usecs; mgr->num_buffers = 0; mgr->bypass_usage = bypass_usage; @@ -299,4 +312,6 @@ pb_cache_deinit(struct pb_cache *mgr) { pb_cache_release_all_buffers(mgr); mtx_destroy(&mgr->mutex); + FREE(mgr->buckets); + mgr->buckets = NULL; } diff --git a/src/gallium/auxiliary/pipebuffer/pb_cache.h b/src/gallium/auxiliary/pipebuffer/pb_cache.h index d082eca8b5d..904095c38b5 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_cache.h +++ b/src/gallium/auxiliary/pipebuffer/pb_cache.h @@ -50,11 +50,12 @@ struct pb_cache /* The cache is divided into buckets for minimizing cache misses. * The driver controls which buffer goes into which bucket. */ - struct list_head buckets[4]; + struct list_head *buckets; mtx_t mutex; uint64_t cache_size; uint64_t max_cache_size; + unsigned num_heaps; unsigned usecs; unsigned num_buffers; unsigned bypass_usage; @@ -71,7 +72,8 @@ struct pb_buffer *pb_cache_reclaim_buffer(struct pb_cache *mgr, pb_size size, void pb_cache_release_all_buffers(struct pb_cache *mgr); void pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry, struct pb_buffer *buf, unsigned bucket_index); -void pb_cache_init(struct pb_cache *mgr, uint usecs, float size_factor, +void pb_cache_init(struct pb_cache *mgr, uint num_heaps, + uint usecs, float size_factor, unsigned bypass_usage, uint64_t maximum_cache_size, void (*destroy_buffer)(struct pb_buffer *buf), bool (*can_reclaim)(struct pb_buffer *buf)); -- cgit v1.2.3