Skip to content

Commit

Permalink
buffer: Add buffer range allocation functions
Browse files Browse the repository at this point in the history
Two new buffer allocation functions buffer_set_size_range and
buffer_alloc_range dedicated to deep buffering have been added. They try to
allocate the largest possible buffer according to the suggested size. If
this size cannot be obtained, it will be reduced step by step until it
reaches the minimum size.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
  • Loading branch information
softwarecki committed May 22, 2024
1 parent 2f36b3c commit f5e363f
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
101 changes: 101 additions & 0 deletions src/audio/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,50 @@ int buffer_sync_shadow_dp_queue(struct comp_buffer *buffer, size_t limit)
}
#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */

struct comp_buffer *buffer_alloc_range(uint32_t preferred_size, uint32_t minimum_size,
uint32_t caps, uint32_t flags, uint32_t align,
bool is_shared)
{
struct comp_buffer *buffer;
uint32_t size;
void *stream_addr = NULL;

tr_dbg(&buffer_tr, "buffer_alloc_range(): %u -- %u bytes", minimum_size, preferred_size);

/* validate request */
if (minimum_size == 0 || preferred_size < minimum_size) {
tr_err(&buffer_tr, "buffer_alloc_range(): new size range %u -- %u is invalid",
minimum_size, preferred_size);
return NULL;
}

/* Align preferred size to a multiple of the minimum size */
if (preferred_size % minimum_size)
preferred_size += minimum_size - preferred_size % minimum_size;

for (size = preferred_size; size >= minimum_size; size -= minimum_size) {
stream_addr = rballoc_align(0, caps, size, align);
if (stream_addr)
break;
}

tr_dbg(&buffer_tr, "buffer_alloc_range(): allocated %u bytes", size);

if (!stream_addr) {
tr_err(&buffer_tr, "buffer_alloc_range(): could not alloc size = %u bytes of type = %u",
minimum_size, caps);
return NULL;
}

buffer = buffer_alloc_struct(stream_addr, size, caps, flags, is_shared);
if (!buffer) {
tr_err(&buffer_tr, "buffer_alloc_range(): could not alloc buffer structure");
rfree(stream_addr);
}

return buffer;
}

void buffer_zero(struct comp_buffer *buffer)
{
buf_dbg(buffer, "stream_zero()");
Expand Down Expand Up @@ -215,6 +259,63 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignmen
return 0;
}

int buffer_set_size_range(struct comp_buffer *buffer, uint32_t preferred_size,
uint32_t minimum_size, uint32_t alignment)
{
void *ptr = audio_stream_get_addr(&buffer->stream);
const uint32_t size = audio_stream_get_size(&buffer->stream);
void *new_ptr = NULL;
uint32_t new_size;

CORE_CHECK_STRUCT(buffer);

/* validate request */
if (minimum_size == 0 || preferred_size < minimum_size) {
buf_err(buffer, "resize size range %u -- %u is invalid", minimum_size,
preferred_size);
return -EINVAL;
}

/* Align preferred size to a multiple of the minimum size */
if (preferred_size % minimum_size)
preferred_size += minimum_size - preferred_size % minimum_size;

if (preferred_size == audio_stream_get_size(&buffer->stream))
return 0;

if (!alignment) {
for (new_size = preferred_size; new_size >= minimum_size;
new_size -= minimum_size) {
new_ptr = rbrealloc(ptr, SOF_MEM_FLAG_NO_COPY, buffer->caps, new_size,
size);
if (new_ptr)
break;
}
} else {
for (new_size = preferred_size; new_size >= minimum_size;
new_size -= minimum_size) {
new_ptr = rbrealloc_align(ptr, SOF_MEM_FLAG_NO_COPY, buffer->caps, new_size,
size, alignment);
if (new_ptr)
break;
}
}

/* we couldn't allocate bigger chunk */
if (!new_ptr && new_size > size) {
buf_err(buffer, "resize can't alloc %u bytes type %u", new_size, buffer->caps);
return -ENOMEM;
}

/* use bigger chunk, else just use the old chunk but set smaller */
if (new_ptr)
buffer->stream.addr = new_ptr;

buffer_init_stream(buffer, size);

return 0;
}

int buffer_set_params(struct comp_buffer *buffer,
struct sof_ipc_stream_params *params, bool force_update)
{
Expand Down
5 changes: 5 additions & 0 deletions src/include/sof/audio/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ struct buffer_cb_free {
/* pipeline buffer creation and destruction */
struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, uint32_t align,
bool is_shared);
struct comp_buffer *buffer_alloc_range(uint32_t preferred_size, uint32_t minimum_size,
uint32_t caps, uint32_t flags, uint32_t align,
bool is_shared);
struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared);
#if CONFIG_ZEPHYR_DP_SCHEDULER
/*
Expand Down Expand Up @@ -226,6 +229,8 @@ int buffer_create_shadow_dp_queue(struct comp_buffer *buffer, bool at_input);
int buffer_sync_shadow_dp_queue(struct comp_buffer *buffer, size_t limit);
#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */
int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignment);
int buffer_set_size_range(struct comp_buffer *buffer, uint32_t preferred_size,
uint32_t minimum_size, uint32_t alignment);
void buffer_free(struct comp_buffer *buffer);
void buffer_zero(struct comp_buffer *buffer);

Expand Down

0 comments on commit f5e363f

Please sign in to comment.