mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-19 07:00:10 -05:00
alloc: improve alignment in alloactor
link: use buffer allocator Add more tests
This commit is contained in:
parent
30ecf66561
commit
93e8074b2c
5 changed files with 89 additions and 103 deletions
|
|
@ -41,10 +41,12 @@ struct spa_buffer_alloc_info {
|
|||
uint32_t n_datas;
|
||||
struct spa_data *datas;
|
||||
uint32_t *data_aligns;
|
||||
uint32_t max_align; /**< max of all alignments */
|
||||
size_t skel_size; /**< size of the struct spa_buffer and inlined meta/chunk/data */
|
||||
size_t meta_size; /**< size of the meta if not inlined */
|
||||
size_t chunk_size; /**< size of the chunk if not inlined */
|
||||
size_t data_size; /**< size of the data if not inlined */
|
||||
size_t mem_size; /**< size of the total memory if not inlined */
|
||||
};
|
||||
|
||||
static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
||||
|
|
@ -60,6 +62,8 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
|||
info->n_datas = n_datas;
|
||||
info->datas = datas;
|
||||
info->data_aligns = data_aligns;
|
||||
info->max_align = 16;
|
||||
info->mem_size = 0;
|
||||
|
||||
info->skel_size = sizeof(struct spa_buffer);
|
||||
info->skel_size += n_metas * sizeof(struct spa_meta);
|
||||
|
|
@ -71,12 +75,17 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
|||
|
||||
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_META))
|
||||
info->skel_size += info->meta_size;
|
||||
else
|
||||
info->mem_size += info->meta_size;
|
||||
|
||||
info->chunk_size = n_datas * sizeof(struct spa_chunk);
|
||||
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK))
|
||||
info->skel_size += info->chunk_size;
|
||||
else
|
||||
info->mem_size += info->chunk_size;
|
||||
|
||||
for (i = 0, size = 0; i < n_datas; i++) {
|
||||
info->max_align = SPA_MAX(info->max_align, data_aligns[i]);
|
||||
size = SPA_ROUND_UP_N(size, data_aligns[i]);
|
||||
size += datas[i].maxsize;
|
||||
}
|
||||
|
|
@ -84,10 +93,15 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
|||
|
||||
if (!SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_NO_DATA) &&
|
||||
SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_DATA)) {
|
||||
info->skel_size += n_datas ? data_aligns[0] - 1 : 0;
|
||||
info->skel_size = SPA_ROUND_UP_N(info->skel_size, n_datas ? data_aligns[0] : 1);
|
||||
info->skel_size += info->data_size;
|
||||
info->skel_size = SPA_ROUND_UP_N(info->skel_size, info->max_align);
|
||||
}
|
||||
else {
|
||||
info->mem_size = SPA_ROUND_UP_N(info->mem_size, n_datas ? data_aligns[0] : 1);
|
||||
info->mem_size += info->data_size;
|
||||
info->mem_size = SPA_ROUND_UP_N(info->mem_size, info->max_align);
|
||||
}
|
||||
info->skel_size = SPA_ROUND_UP_N(info->skel_size, 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -157,11 +171,10 @@ spa_buffer_alloc_layout_array(struct spa_buffer_alloc_info *info,
|
|||
void *skel_mem, void *data_mem)
|
||||
{
|
||||
uint32_t i;
|
||||
size_t data_size = info->data_size + info->meta_size + info->chunk_size;
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
buffers[i] = spa_buffer_alloc_layout(info, skel_mem, data_mem);
|
||||
skel_mem = SPA_MEMBER(skel_mem, info->skel_size, void);
|
||||
data_mem = SPA_MEMBER(data_mem, data_size, void);
|
||||
data_mem = SPA_MEMBER(data_mem, info->mem_size, void);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -173,19 +186,21 @@ spa_buffer_alloc_array(uint32_t n_buffers, uint32_t flags,
|
|||
uint32_t data_aligns[])
|
||||
{
|
||||
|
||||
struct spa_buffer **buffers;
|
||||
struct spa_buffer_alloc_info info = { flags | SPA_BUFFER_ALLOC_FLAG_INLINE_ALL, };
|
||||
void *skel;
|
||||
struct spa_buffer **buffers;
|
||||
struct spa_buffer_alloc_info info = { flags | SPA_BUFFER_ALLOC_FLAG_INLINE_ALL, };
|
||||
void *skel;
|
||||
|
||||
spa_buffer_alloc_fill_info(&info, n_metas, metas, n_datas, datas, data_aligns);
|
||||
spa_buffer_alloc_fill_info(&info, n_metas, metas, n_datas, datas, data_aligns);
|
||||
|
||||
buffers = (struct spa_buffer **)calloc(n_buffers, sizeof(struct spa_buffer *) + info.skel_size);
|
||||
buffers = (struct spa_buffer **)calloc(1, info.max_align +
|
||||
n_buffers * (sizeof(struct spa_buffer *) + info.skel_size));
|
||||
|
||||
skel = SPA_MEMBER(buffers, sizeof(struct spa_buffer *) * n_buffers, void);
|
||||
skel = SPA_MEMBER(buffers, sizeof(struct spa_buffer *) * n_buffers, void);
|
||||
skel = SPA_PTR_ALIGN(skel, info.max_align, void);
|
||||
|
||||
spa_buffer_alloc_layout_array(&info, n_buffers, buffers, skel, NULL);
|
||||
spa_buffer_alloc_layout_array(&info, n_buffers, buffers, skel, NULL);
|
||||
|
||||
return buffers;
|
||||
return buffers;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ static void test_alloc(void)
|
|||
{
|
||||
struct spa_buffer **buffers;
|
||||
struct spa_meta metas[4];
|
||||
struct spa_data datas[4];
|
||||
uint32_t aligns[4];
|
||||
int i, j;
|
||||
struct spa_data datas[2];
|
||||
uint32_t aligns[2];
|
||||
uint32_t i, j;
|
||||
|
||||
metas[0].type = SPA_META_Header;
|
||||
metas[0].size = sizeof(struct spa_meta_header);
|
||||
|
|
@ -72,28 +72,40 @@ static void test_alloc(void)
|
|||
sizeof(struct spa_meta_bitmap) + w * h * bpp)
|
||||
metas[2].type = SPA_META_Cursor;
|
||||
metas[2].size = CURSOR_META_SIZE(64,64,4);
|
||||
metas[3].type = 101;
|
||||
metas[3].size = 11;
|
||||
|
||||
datas[0].maxsize = 4096;
|
||||
datas[1].maxsize = 2048;
|
||||
datas[0].maxsize = 4000;
|
||||
datas[1].maxsize = 2011;
|
||||
|
||||
aligns[0] = 16;
|
||||
aligns[0] = 32;
|
||||
aligns[1] = 16;
|
||||
|
||||
buffers = spa_buffer_alloc_array(16, 0, 3, metas, 2, datas, aligns);
|
||||
buffers = spa_buffer_alloc_array(16, 0,
|
||||
SPA_N_ELEMENTS(metas), metas,
|
||||
SPA_N_ELEMENTS(datas), datas, aligns);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
fprintf(stderr, "buffers %p\n", buffers);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
struct spa_buffer *b = buffers[i];
|
||||
fprintf(stderr, "buffer %d %p\n", i, b);
|
||||
|
||||
spa_assert(b->n_metas == 3);
|
||||
spa_assert(b->n_datas == 2);
|
||||
spa_assert(b->n_metas == SPA_N_ELEMENTS(metas));
|
||||
spa_assert(b->n_datas == SPA_N_ELEMENTS(datas));
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (j = 0; j < SPA_N_ELEMENTS(metas); j++) {
|
||||
spa_assert(b->metas[j].type == metas[j].type);
|
||||
spa_assert(b->metas[j].size == metas[j].size);
|
||||
fprintf(stderr, " meta %d %p\n", j, b->metas[j].data);
|
||||
spa_assert(SPA_IS_ALIGNED(b->metas[j].data, 8));
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (j = 0; j < SPA_N_ELEMENTS(datas); j++) {
|
||||
spa_assert(b->datas[j].maxsize == datas[j].maxsize);
|
||||
fprintf(stderr, " data %d %p %p\n", j, b->datas[j].chunk, b->datas[j].data);
|
||||
spa_assert(SPA_IS_ALIGNED(b->datas[j].chunk, 8));
|
||||
spa_assert(SPA_IS_ALIGNED(b->datas[j].data, aligns[j]));
|
||||
}
|
||||
}
|
||||
free(buffers);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue