Module: Mesa Branch: main Commit: 89afcc94eadbdd3d0acf8680db37e95c3dd20ec0 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=89afcc94eadbdd3d0acf8680db37e95c3dd20ec0
Author: Caio Oliveira <[email protected]> Date: Mon Oct 2 22:35:04 2023 -0700 util: Add a way to set the min_buffer_size in linear_alloc The default value remains 2048, which is also used for rounding up any user provided size. The option is useful in cases where there's a better idea of the amount of data that's going to be used. Reviewed-by: Marek Olšák <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25279> --- src/util/ralloc.c | 29 ++++++++++++++++++++++------- src/util/ralloc.h | 6 ++++++ src/util/tests/linear_test.cpp | 19 +++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/util/ralloc.c b/src/util/ralloc.c index c85c61e3d8a..95b80a87991 100644 --- a/src/util/ralloc.c +++ b/src/util/ralloc.c @@ -964,7 +964,6 @@ gc_sweep_end(gc_ctx *ctx) * other buffers. */ -#define MIN_LINEAR_BUFSIZE 2048 #define SUBALLOC_ALIGNMENT 8 #define LMAGIC_CONTEXT 0x87b9c7d3 #define LMAGIC_NODE 0x87b910d3 @@ -976,6 +975,8 @@ struct linear_ctx { #ifndef NDEBUG unsigned magic; /* for debugging */ #endif + unsigned min_buffer_size; + unsigned offset; /* points to the first unused byte in the latest buffer */ unsigned size; /* size of the latest buffer */ void *latest; /* the only buffer that has free space */ @@ -1021,9 +1022,9 @@ linear_alloc_child(linear_ctx *ctx, unsigned size) if (unlikely(ctx->offset + size > ctx->size)) { /* allocate a new node */ unsigned node_size = size; - if (likely(node_size < MIN_LINEAR_BUFSIZE)) - node_size = MIN_LINEAR_BUFSIZE; - + if (likely(node_size < ctx->min_buffer_size)) + node_size = ctx->min_buffer_size; + const unsigned canary_size = get_node_canary_size(); const unsigned full_size = canary_size + node_size; @@ -1070,21 +1071,35 @@ linear_alloc_child(linear_ctx *ctx, unsigned size) linear_ctx * linear_context(void *ralloc_ctx) +{ + const linear_opts opts = {0}; + return linear_context_with_opts(ralloc_ctx, &opts); +} + +linear_ctx * +linear_context_with_opts(void *ralloc_ctx, const linear_opts *opts) { linear_ctx *ctx; if (unlikely(!ralloc_ctx)) return NULL; - const unsigned size = MIN_LINEAR_BUFSIZE; + const unsigned default_min_buffer_size = 2048; + const unsigned min_buffer_size = + MAX2(ALIGN_POT(opts->min_buffer_size, default_min_buffer_size), + default_min_buffer_size); + + const unsigned size = min_buffer_size; const unsigned canary_size = get_node_canary_size(); const unsigned full_size = - sizeof(linear_ctx) + canary_size + size; + sizeof(linear_ctx) + canary_size + size; ctx = ralloc_size(ralloc_ctx, full_size); if (unlikely(!ctx)) return NULL; + ctx->min_buffer_size = min_buffer_size; + ctx->offset = 0; ctx->size = size; ctx->latest = (char *)&ctx[1] + canary_size; @@ -1125,7 +1140,7 @@ ralloc_steal_linear_context(void *new_ralloc_ctx, linear_ctx *ctx) { if (unlikely(!ctx)) return; - + assert(ctx->magic == LMAGIC_CONTEXT); /* Linear context is also the ralloc parent of extra nodes. */ diff --git a/src/util/ralloc.h b/src/util/ralloc.h index 58d851f1823..2078a88ff07 100644 --- a/src/util/ralloc.h +++ b/src/util/ralloc.h @@ -579,6 +579,10 @@ typedef struct linear_ctx linear_ctx; */ void *linear_alloc_child(linear_ctx *ctx, unsigned size); +typedef struct { + unsigned min_buffer_size; +} linear_opts; + /** * Allocate a linear context that will internally hold linear buffers. * Use it for all child node allocations. @@ -587,6 +591,8 @@ void *linear_alloc_child(linear_ctx *ctx, unsigned size); */ linear_ctx *linear_context(void *ralloc_ctx); +linear_ctx *linear_context_with_opts(void *ralloc_ctx, const linear_opts *opts); + /** * Same as linear_alloc_child, but also clears memory. */ diff --git a/src/util/tests/linear_test.cpp b/src/util/tests/linear_test.cpp index 2b573184515..5b7c5525a7e 100644 --- a/src/util/tests/linear_test.cpp +++ b/src/util/tests/linear_test.cpp @@ -70,3 +70,22 @@ TEST(LinearAlloc, AvoidWasteAfterLargeAlloc) ralloc_free(ctx); } + +TEST(LinearAlloc, Options) +{ + void *ctx = ralloc_context(NULL); + + linear_opts opts = {}; + opts.min_buffer_size = 8192; + + linear_ctx *lin_ctx = linear_context_with_opts(ctx, &opts); + + /* Assert allocations spanning the first 8192 bytes are contiguous. */ + char *first = (char *)linear_alloc_child(lin_ctx, 1024); + for (int i = 1; i < 8; i++) { + char *ptr = (char *)linear_alloc_child(lin_ctx, 1024); + EXPECT_EQ(ptr - first, 1024 * i); + } + + ralloc_free(ctx); +}
